summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/r0drv
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Runtime/r0drv
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Runtime/r0drv')
-rw-r--r--src/VBox/Runtime/r0drv/alloc-r0drv.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/alloc-r0drv.h2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp8
-rw-r--r--src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp3
-rw-r--r--src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h8
-rw-r--r--src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp6
-rw-r--r--src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c5
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c63
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c3
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c7
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h6
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h4
-rw-r--r--src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c2
-rw-r--r--src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp84
-rw-r--r--src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c42
-rw-r--r--src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c41
-rw-r--r--src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c124
-rw-r--r--src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c68
-rw-r--r--src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c48
-rw-r--r--src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c663
-rw-r--r--src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c218
-rw-r--r--src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c46
-rw-r--r--src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c264
-rw-r--r--src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c291
-rw-r--r--src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c120
-rw-r--r--src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c233
-rw-r--r--src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c146
-rw-r--r--src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h114
-rw-r--r--src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c127
-rw-r--r--src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c131
-rw-r--r--src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c79
-rw-r--r--src/VBox/Runtime/r0drv/initterm-r0drv.cpp17
-rw-r--r--src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c10
-rw-r--r--src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c33
-rw-r--r--src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c15
-rw-r--r--src/VBox/Runtime/r0drv/linux/string.h2
-rw-r--r--src/VBox/Runtime/r0drv/linux/the-linux-kernel.h14
-rw-r--r--src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c6
-rw-r--r--src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c330
-rw-r--r--src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c2
-rw-r--r--src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c4
-rw-r--r--src/VBox/Runtime/r0drv/memobj-r0drv.cpp10
-rw-r--r--src/VBox/Runtime/r0drv/mp-r0drv.h2
-rw-r--r--src/VBox/Runtime/r0drv/mpnotification-r0drv.c4
-rw-r--r--src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp349
-rw-r--r--src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h4
-rw-r--r--src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp1203
-rw-r--r--src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp8
-rw-r--r--src/VBox/Runtime/r0drv/nt/symdb.h85
-rw-r--r--src/VBox/Runtime/r0drv/nt/symdbdata.h2920
-rw-r--r--src/VBox/Runtime/r0drv/nt/the-nt-kernel.h2
-rw-r--r--src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp7
-rw-r--r--src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp26
-rw-r--r--src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp17
-rw-r--r--src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp2
-rw-r--r--src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp4
-rw-r--r--src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp4
-rw-r--r--src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp3
-rw-r--r--src/VBox/Runtime/r0drv/power-r0drv.h2
-rw-r--r--src/VBox/Runtime/r0drv/powernotification-r0drv.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c11
-rw-r--r--src/VBox/Runtime/r0drv/solaris/RTMpPokeCpu-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/alloc-r0drv-solaris.c4
-rw-r--r--src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c28
-rw-r--r--src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c6
-rw-r--r--src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/mp-r0drv-solaris.c8
-rw-r--r--src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/process-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h49
-rw-r--r--src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/thread2-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c337
-rw-r--r--src/VBox/Runtime/r0drv/solaris/time-r0drv-solaris.c2
-rw-r--r--src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c73
131 files changed, 8425 insertions, 266 deletions
diff --git a/src/VBox/Runtime/r0drv/alloc-r0drv.cpp b/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
index 8444838f..c34ffc32 100644
--- a/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
+++ b/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -336,7 +336,7 @@ RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, cons
int rc;
RT_ASSERT_PREEMPT_CPUID_VAR();
- if (!(fFlags & RTMEMHDR_FLAG_ANY_CTX_ALLOC))
+ if (!(fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC))
RT_ASSERT_INTS_ON();
/*
@@ -349,7 +349,7 @@ RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, cons
/*
* Validate and convert flags.
*/
- AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK_R0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
fHdrFlags |= RTMEMHDR_FLAG_ZEROED;
if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
diff --git a/src/VBox/Runtime/r0drv/alloc-r0drv.h b/src/VBox/Runtime/r0drv/alloc-r0drv.h
index 10350fb5..bf790c1f 100644
--- a/src/VBox/Runtime/r0drv/alloc-r0drv.h
+++ b/src/VBox/Runtime/r0drv/alloc-r0drv.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp
index 9a65df82..6b895353 100644
--- a/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/RTLogWriteDebugger-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp
index 57da5a76..bf5e5906 100644
--- a/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/RTLogWriteStdOut-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp
index 15aebedb..c221df41 100644
--- a/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/assert-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007 Oracle Corporation
+ * Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp
index 42e15391..293c4ab2 100644
--- a/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/dbgkrnlinfo-r0drv-darwin.cpp
@@ -57,7 +57,7 @@ RT_C_DECLS_END
#include <iprt/log.h>
#include <iprt/mem.h>
#include <iprt/string.h>
-#include "internal/ldrMach-O.h"
+#include <iprt/formats/mach-o.h>
#include "internal/magics.h"
/** @def MY_CPU_TYPE
diff --git a/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp
index 9cf01463..98ba22ab 100644
--- a/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/initterm-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
index 822b9cd1..6faf85ae 100644
--- a/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
@@ -360,8 +360,7 @@ DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
*/
if (pMemDarwin->pMemDesc)
{
- if (pMemDarwin->Core.enmType == RTR0MEMOBJTYPE_LOCK)
- pMemDarwin->pMemDesc->complete(); /* paranoia */
+ pMemDarwin->pMemDesc->complete();
pMemDarwin->pMemDesc->release();
pMemDarwin->pMemDesc = NULL;
}
@@ -452,7 +451,7 @@ static int rtR0MemObjNativeAllocWorker(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
* we'll use rtR0MemObjNativeAllocCont as a fallback for dealing with that.
*
* The kIOMemoryKernelUserShared flag just forces the result to be page aligned.
- *
+ *
* The kIOMemoryMapperNone flag is required since 10.8.2 (IOMMU changes?).
*/
int rc;
@@ -511,6 +510,7 @@ static int rtR0MemObjNativeAllocWorker(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
&& Addr == AddrPrev + PAGE_SIZE))
{
/* Buggy API, try allocate the memory another way. */
+ pMemDesc->complete();
pMemDesc->release();
if (PhysMask)
LogRel(("rtR0MemObjNativeAllocWorker: off=%x Addr=%llx AddrPrev=%llx MaxPhysAddr=%llx PhysMas=%llx fContiguous=%RTbool fOptions=%#x - buggy API!\n",
@@ -593,6 +593,8 @@ static int rtR0MemObjNativeAllocWorker(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
}
else
rc = VERR_MEMOBJ_INIT_FAILED;
+
+ pMemDesc->complete();
}
else
rc = RTErrConvertFromDarwinIO(IORet);
diff --git a/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp
index edd6c671..1c167327 100644
--- a/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/memuserkernel-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -110,4 +110,3 @@ RTR0DECL(int) RTR0MemKernelCopyTo(void *pvDst, void const *pvSrc, size_t cb)
return VERR_NOT_SUPPORTED;
}
-
diff --git a/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp
index f5a73166..48d0e097 100644
--- a/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/mp-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp
index 35542030..71ce84de 100644
--- a/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/process-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp
index cf57135a..9a216f4a 100644
--- a/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semevent-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp
index a77d41d0..9239860b 100644
--- a/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semeventmulti-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp
index 2b01e760..ef0f9d87 100644
--- a/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/semmutex-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp
index 26d934a8..bc744dac 100644
--- a/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h b/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
index cad8dc95..d8be50d6 100644
--- a/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
+++ b/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -85,6 +85,12 @@
# define AST_URGENT UINT32_C(4)
#endif
+/* This flag was added in 10.6, it seems. Should be harmless in earlier
+ releases... */
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+# define kIOMemoryMapperNone UINT32_C(0x800)
+#endif
+
RT_C_DECLS_BEGIN
diff --git a/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
index e603e9e1..0bce605b 100644
--- a/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
index 64cabf79..139c0156 100644
--- a/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp
index 23b28a10..b636e1d8 100644
--- a/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -109,8 +109,8 @@ RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
uint32_t volatile *pfAstPending = g_pfnR0DarwinAstPending(); AssertPtr(pfAstPending);
uint32_t const fAstPending = *pfAstPending;
- AssertMsg(!(fAstPending & UINT32_C(0xfffff000)), ("%#x\n", fAstPending));
- return (fAstPending & (AST_PREEMPT | AST_URGENT)) != 0;
+ AssertMsg(!(fAstPending & UINT32_C(0xffff8000)), ("%#x\n", fAstPending));
+ return (fAstPending & (AST_PREEMPT | AST_QUANTUM | AST_URGENT)) != 0;
}
diff --git a/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp b/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp
index 913fa711..4d9ef806 100644
--- a/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp
+++ b/src/VBox/Runtime/r0drv/darwin/time-r0drv-darwin.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
index 349ad7bb..b6c3d231 100644
--- a/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
@@ -79,8 +79,13 @@ DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
return VERR_NO_EXEC_MEMORY;
/* Addr contains a start address vm_map_find will start searching for suitable space at. */
+#if __FreeBSD_version >= 1000055
+ int rc = vm_map_find(kernel_map, pVmObject, 0, &Addr,
+ cbAllocated, 0, VMFS_ANY_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0);
+#else
int rc = vm_map_find(kernel_map, pVmObject, 0, &Addr,
cbAllocated, TRUE, VM_PROT_ALL, VM_PROT_ALL, 0);
+#endif
if (rc == KERN_SUCCESS)
{
rc = vm_map_wire(kernel_map, Addr, Addr + cbAllocated,
diff --git a/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
index 5c90cf38..2486fd13 100644
--- a/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
@@ -162,7 +162,11 @@ DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
case RTR0MEMOBJTYPE_PHYS:
case RTR0MEMOBJTYPE_PHYS_NC:
{
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WLOCK(pMemFreeBSD->pObject);
+#else
VM_OBJECT_LOCK(pMemFreeBSD->pObject);
+#endif
vm_page_t pPage = vm_page_find_least(pMemFreeBSD->pObject, 0);
vm_page_lock_queues();
for (vm_page_t pPage = vm_page_find_least(pMemFreeBSD->pObject, 0);
@@ -172,7 +176,11 @@ DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
vm_page_unwire(pPage, 0);
}
vm_page_unlock_queues();
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WUNLOCK(pMemFreeBSD->pObject);
+#else
VM_OBJECT_UNLOCK(pMemFreeBSD->pObject);
+#endif
vm_object_deallocate(pMemFreeBSD->pObject);
break;
}
@@ -200,10 +208,18 @@ static vm_page_t rtR0MemObjFreeBSDContigPhysAllocHelper(vm_object_t pObject, vm_
while (cTries <= 1)
{
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WLOCK(pObject);
+#else
VM_OBJECT_LOCK(pObject);
+#endif
pPages = vm_page_alloc_contig(pObject, iPIndex, fFlags, cPages, 0,
VmPhysAddrHigh, uAlignment, 0, VM_MEMATTR_DEFAULT);
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WUNLOCK(pObject);
+#else
VM_OBJECT_UNLOCK(pObject);
+#endif
if (pPages)
break;
vm_pageout_grow_cache(cTries, 0, VmPhysAddrHigh);
@@ -223,7 +239,11 @@ static vm_page_t rtR0MemObjFreeBSDContigPhysAllocHelper(vm_object_t pObject, vm_
if (!pPages)
return pPages;
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WLOCK(pObject);
+#else
VM_OBJECT_LOCK(pObject);
+#endif
for (vm_pindex_t iPage = 0; iPage < cPages; iPage++)
{
vm_page_t pPage = pPages + iPage;
@@ -235,7 +255,11 @@ static vm_page_t rtR0MemObjFreeBSDContigPhysAllocHelper(vm_object_t pObject, vm_
atomic_add_int(&cnt.v_wire_count, 1);
}
}
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WUNLOCK(pObject);
+#else
VM_OBJECT_UNLOCK(pObject);
+#endif
return pPages;
#endif
}
@@ -259,7 +283,11 @@ static int rtR0MemObjFreeBSDPhysAllocHelper(vm_object_t pObject, u_long cPages,
if (!pPage)
{
/* Free all allocated pages */
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WLOCK(pObject);
+#else
VM_OBJECT_LOCK(pObject);
+#endif
while (iPage-- > 0)
{
pPage = vm_page_lookup(pObject, iPage);
@@ -269,7 +297,11 @@ static int rtR0MemObjFreeBSDPhysAllocHelper(vm_object_t pObject, u_long cPages,
vm_page_free(pPage);
vm_page_unlock_queues();
}
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WUNLOCK(pObject);
+#else
VM_OBJECT_UNLOCK(pObject);
+#endif
return rcNoMem;
}
}
@@ -286,9 +318,15 @@ static int rtR0MemObjFreeBSDAllocHelper(PRTR0MEMOBJFREEBSD pMemFreeBSD, bool fEx
pMemFreeBSD->pObject = vm_object_allocate(OBJT_PHYS, cPages);
/* No additional object reference for auto-deallocation upon unmapping. */
+#if __FreeBSD_version >= 1000055
+ rc = vm_map_find(kernel_map, pMemFreeBSD->pObject, 0,
+ &MapAddress, pMemFreeBSD->Core.cb, 0, VMFS_ANY_SPACE,
+ fExecutable ? VM_PROT_ALL : VM_PROT_RW, VM_PROT_ALL, 0);
+#else
rc = vm_map_find(kernel_map, pMemFreeBSD->pObject, 0,
&MapAddress, pMemFreeBSD->Core.cb, VMFS_ANY_SPACE,
fExecutable ? VM_PROT_ALL : VM_PROT_RW, VM_PROT_ALL, 0);
+#endif
if (rc == KERN_SUCCESS)
{
@@ -402,9 +440,17 @@ static int rtR0MemObjFreeBSDAllocPhysPages(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOB
if (fContiguous)
{
Assert(enmType == RTR0MEMOBJTYPE_PHYS);
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WLOCK(pMemFreeBSD->pObject);
+#else
VM_OBJECT_LOCK(pMemFreeBSD->pObject);
+#endif
pMemFreeBSD->Core.u.Phys.PhysBase = VM_PAGE_TO_PHYS(vm_page_find_least(pMemFreeBSD->pObject, 0));
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WUNLOCK(pMemFreeBSD->pObject);
+#else
VM_OBJECT_UNLOCK(pMemFreeBSD->pObject);
+#endif
pMemFreeBSD->Core.u.Phys.fAllocated = true;
}
@@ -551,6 +597,9 @@ static int rtR0MemObjNativeReserveInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixe
0, /* offset */
&MapAddress, /* addr (IN/OUT) */
cb, /* length */
+#if __FreeBSD_version >= 1000055
+ 0, /* max addr */
+#endif
pvFixed == (void *)-1 ? VMFS_ANY_SPACE : VMFS_NO_SPACE,
/* find_space */
VM_PROT_NONE, /* protection */
@@ -628,6 +677,9 @@ DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ
offSub, /* Start offset in the object */
&Addr, /* Start address IN/OUT */
cbSub, /* Size of the mapping */
+#if __FreeBSD_version >= 1000055
+ 0, /* Upper bound of mapping */
+#endif
VMFS_ANY_SPACE, /* Whether a suitable address should be searched for first */
ProtectionFlags, /* protection flags */
VM_PROT_ALL, /* Maximum protection flags */
@@ -704,6 +756,9 @@ DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ p
0, /* Start offset in the object */
&AddrR3, /* Start address IN/OUT */
pMemToMap->cb, /* Size of the mapping */
+#if __FreeBSD_version >= 1000055
+ 0, /* Upper bound of the mapping */
+#endif
R3PtrFixed == (RTR3PTR)-1 ? VMFS_ANY_SPACE : VMFS_NO_SPACE,
/* Whether a suitable address should be searched for first */
ProtectionFlags, /* protection flags */
@@ -814,9 +869,17 @@ DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, s
case RTR0MEMOBJTYPE_PHYS_NC:
{
RTHCPHYS addr;
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WLOCK(pMemFreeBSD->pObject);
+#else
VM_OBJECT_LOCK(pMemFreeBSD->pObject);
+#endif
addr = VM_PAGE_TO_PHYS(vm_page_lookup(pMemFreeBSD->pObject, iPage));
+#if __FreeBSD_version >= 1000030
+ VM_OBJECT_WUNLOCK(pMemFreeBSD->pObject);
+#else
VM_OBJECT_UNLOCK(pMemFreeBSD->pObject);
+#endif
return addr;
}
diff --git a/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c
index be8006b3..d7fa0b2d 100644
--- a/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/memuserkernel-r0drv-freebsd.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -81,4 +81,3 @@ RTR0DECL(int) RTR0MemKernelCopyTo(void *pvDst, void const *pvSrc, size_t cb)
return VERR_NOT_SUPPORTED;
}
-
diff --git a/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c
index 87e82ff2..a38e78a3 100644
--- a/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/mp-r0drv-freebsd.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -88,6 +88,11 @@ RTDECL(RTCPUID) RTMpGetCount(void)
}
+RTDECL(RTCPUID) RTMpGetCoreCount(void)
+{
+ return mp_maxid + 1;
+}
+
RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
{
return idCpu <= mp_maxid
diff --git a/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c
index b20b9603..addd9d01 100644
--- a/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h b/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h
index 2d0201d9..0a0be656 100644
--- a/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h
+++ b/src/VBox/Runtime/r0drv/freebsd/sleepqueue-r0drv-freebsd.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -36,7 +36,7 @@
#include <iprt/time.h>
/**
- * Kernel mode Linux wait state structure.
+ * Kernel mode FreeBSD wait state structure.
*/
typedef struct RTR0SEMBSDSLEEP
{
@@ -259,7 +259,7 @@ DECLINLINE(void) rtR0SemBsdWaitDoIt(PRTR0SEMBSDSLEEP pWait)
*
* @returns true / false
* @param pWait The wait structure.
- * @remarks This shall be called before the first rtR0SemLnxWaitDoIt().
+ * @remarks This shall be called before the first rtR0SemBsdWaitDoIt().
*/
DECLINLINE(bool) rtR0SemBsdWaitWasInterrupted(PRTR0SEMBSDSLEEP pWait)
{
diff --git a/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h b/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h
index 718b6741..306bb3af 100644
--- a/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h
+++ b/src/VBox/Runtime/r0drv/freebsd/the-freebsd-kernel.h
@@ -50,6 +50,9 @@
#include <sys/unistd.h>
#include <sys/kthread.h>
#include <sys/lock.h>
+#if __FreeBSD_version >= 1000030
+#include <sys/rwlock.h>
+#endif
#include <sys/mutex.h>
#include <sys/sched.h>
#include <sys/callout.h>
@@ -66,6 +69,7 @@
#include <vm/vm_page.h>
#include <vm/vm_phys.h> /* vm_phys_alloc_* */
#include <vm/vm_extern.h> /* kmem_alloc_attr */
+#include <vm/vm_pageout.h> /* vm_contig_grow_cache */
#include <sys/vmmeter.h> /* cnt */
#include <sys/resourcevar.h>
#include <machine/cpu.h>
diff --git a/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c
index d61e6f0b..de14e764 100644
--- a/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2009 Oracle Corporation
+ * Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp
index 925842eb..c8d93f53 100644
--- a/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp
index a9844ace..ba352a63 100644
--- a/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTMpOn-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp
index 01835679..52db8375 100644
--- a/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTMpPokeCpu-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp
index 0d943b3b..3a81521f 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp
index 0e00439d..107971a3 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp
index 1fc9b894..3eaf98a1 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPending-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp
index fe94d022..44057f0b 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptIsPendingTrusty-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp
index 9fa8461e..ef2c2dc1 100644
--- a/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp
index 5310c13b..9a1406cf 100644
--- a/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp
+++ b/src/VBox/Runtime/r0drv/generic/mpnotification-r0drv-generic.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c b/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c
index 69f29f24..7044961c 100644
--- a/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c
+++ b/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp b/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp
new file mode 100644
index 00000000..cce89ba6
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp
@@ -0,0 +1,84 @@
+/* $Id: threadctxhooks-r0drv-generic.cpp $ */
+/** @file
+ * IPRT - Thread-Context Hooks, Ring-0 Driver, Generic.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <iprt/thread.h>
+#include <iprt/err.h>
+
+#include "internal/iprt.h"
+
+RTDECL(int) RTThreadCtxHooksCreate(PRTTHREADCTX phThreadCtx)
+{
+ NOREF(phThreadCtx);
+ return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksCreate);
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRelease(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return UINT32_MAX;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRelease);
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRetain(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return UINT32_MAX;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRetain);
+
+
+RTDECL(int) RTThreadCtxHooksRegister(RTTHREADCTX hThreadCtx, PFNRTTHREADCTXHOOK pfnCallback, void *pvUser)
+{
+ NOREF(hThreadCtx);
+ NOREF(pfnCallback);
+ NOREF(pvUser);
+ return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRegister);
+
+
+RTDECL(int) RTThreadCtxHooksDeregister(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksDeregister);
+
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return false;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksAreRegistered);
+
diff --git a/src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c
new file mode 100644
index 00000000..7d67906f
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c
@@ -0,0 +1,42 @@
+/* $Id: RTLogWriteDebugger-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Log To Debugger, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/log.h>
+
+
+RTDECL(void) RTLogWriteDebugger(const char *pch, size_t cb)
+{
+ /** @todo implement this */
+ /*kprintf("%.*s", (int)cb, pch);*/
+ return;
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c
new file mode 100644
index 00000000..80996090
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c
@@ -0,0 +1,41 @@
+/* $Id: RTLogWriteStdOut-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Log To StdOut, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/log.h>
+
+
+RTDECL(void) RTLogWriteStdOut(const char *pch, size_t cb)
+{
+ dprintf("%.*s", (int)cb, pch);
+ return;
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c
new file mode 100644
index 00000000..58c72036
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c
@@ -0,0 +1,124 @@
+/* $Id: alloc-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Memory Allocation, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/mem.h>
+#include <iprt/log.h>
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/thread.h>
+#include "r0drv/alloc-r0drv.h"
+
+
+/**
+ * OS specific allocation function.
+ */
+int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+{
+ if (RT_UNLIKELY(fFlags & RTMEMHDR_FLAG_ANY_CTX))
+ return VERR_NOT_SUPPORTED;
+
+ PRTMEMHDR pHdr = (PRTMEMHDR)malloc(cb + sizeof(*pHdr));
+ if (RT_UNLIKELY(!pHdr))
+ {
+ LogRel(("rtR0MemAllocEx(%u, %#x) failed\n",(unsigned)cb + sizeof(*pHdr), fFlags));
+ return VERR_NO_MEMORY;
+ }
+
+ pHdr->u32Magic = RTMEMHDR_MAGIC;
+ pHdr->fFlags = fFlags;
+ pHdr->cb = cb;
+ pHdr->cbReq = cb;
+ *ppHdr = pHdr;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * OS specific free function.
+ */
+void rtR0MemFree(PRTMEMHDR pHdr)
+{
+ pHdr->u32Magic += 1;
+ free(pHdr);
+}
+
+
+RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb) RT_NO_THROW
+{
+ /*
+ * Validate input.
+ */
+ AssertPtr(pPhys);
+ Assert(cb > 0);
+ RT_ASSERT_PREEMPTIBLE();
+
+ /*
+ * Allocate the memory and ensure that the API is still providing
+ * memory that's always below 4GB.
+ */
+ cb = RT_ALIGN_Z(cb, PAGE_SIZE);
+ void *pv;
+ area_id area = create_area("VirtualBox Contig Alloc", &pv, B_ANY_KERNEL_ADDRESS, cb, B_32_BIT_CONTIGUOUS,
+ B_READ_AREA | B_WRITE_AREA);
+ if (area >= 0)
+ {
+ physical_entry physMap[2];
+ if (get_memory_map(pv, cb, physMap, 2)>= B_OK)
+ {
+ *pPhys = physMap[0].address;
+ return pv;
+ }
+ delete_area(area);
+ AssertMsgFailed(("Cannot get_memory_map for contig alloc! cb=%u\n",(unsigned)cb));
+ }
+ else
+ AssertMsgFailed(("Cannot create_area for contig alloc! cb=%u error=0x%08lx\n",(unsigned)cb, area));
+ return NULL;
+}
+
+
+RTR0DECL(void) RTMemContFree(void *pv, size_t cb) RT_NO_THROW
+{
+ RT_ASSERT_PREEMPTIBLE();
+ if (pv)
+ {
+ Assert(cb > 0);
+
+ area_id area = area_for(pv);
+ if (area >= B_OK)
+ delete_area(area);
+ else
+ AssertMsgFailed(("Cannot find area to delete! cb=%u error=0x%08lx\n",(unsigned)cb, area));
+ }
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c
new file mode 100644
index 00000000..8241e9b1
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c
@@ -0,0 +1,68 @@
+/* $Id: assert-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Assertion Workers, Ring-0 Drivers, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/assert.h>
+
+#include <iprt/asm.h>
+#include <iprt/log.h>
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+
+#include "internal/assert.h"
+
+
+void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+{
+ dprintf("\r\n!!Assertion Failed!!\r\n"
+ "Expression: %s\r\n"
+ "Location : %s(%d) %s\r\n",
+ pszExpr, pszFile, uLine, pszFunction);
+}
+
+
+void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+{
+ char szMsg[256];
+
+ RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
+ szMsg[sizeof(szMsg) - 1] = '\0';
+ dprintf("%s", szMsg);
+
+ NOREF(fInitial);
+}
+
+
+RTR0DECL(void) RTR0AssertPanicSystem(void)
+{
+ panic("%s%s", g_szRTAssertMsg1, g_szRTAssertMsg2);
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c
new file mode 100644
index 00000000..3041bea1
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c
@@ -0,0 +1,48 @@
+/* $Id: initterm-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Initialization & Termination, R0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include "internal/initterm.h"
+
+
+int rtR0InitNative(void)
+{
+ return VINF_SUCCESS;
+}
+
+
+void rtR0TermNative(void)
+{
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c
new file mode 100644
index 00000000..8c27a26e
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c
@@ -0,0 +1,663 @@
+/* $Id: memobj-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Ring-0 Memory Objects, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+
+#include <iprt/memobj.h>
+#include <iprt/mem.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include <iprt/log.h>
+#include <iprt/param.h>
+#include <iprt/process.h>
+#include "internal/memobj.h"
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * The Haiku version of the memory object structure.
+ */
+typedef struct RTR0MEMOBJHAIKU
+{
+ /** The core structure. */
+ RTR0MEMOBJINTERNAL Core;
+ /** Area identifier */
+ area_id AreaId;
+} RTR0MEMOBJHAIKU, *PRTR0MEMOBJHAIKU;
+
+
+//MALLOC_DEFINE(M_IPRTMOBJ, "iprtmobj", "IPRT - R0MemObj");
+#if 0
+/**
+ * Gets the virtual memory map the specified object is mapped into.
+ *
+ * @returns VM map handle on success, NULL if no map.
+ * @param pMem The memory object.
+ */
+static vm_map_t rtR0MemObjHaikuGetMap(PRTR0MEMOBJINTERNAL pMem)
+{
+ switch (pMem->enmType)
+ {
+ case RTR0MEMOBJTYPE_PAGE:
+ case RTR0MEMOBJTYPE_LOW:
+ case RTR0MEMOBJTYPE_CONT:
+ return kernel_map;
+
+ case RTR0MEMOBJTYPE_PHYS:
+ case RTR0MEMOBJTYPE_PHYS_NC:
+ return NULL; /* pretend these have no mapping atm. */
+
+ case RTR0MEMOBJTYPE_LOCK:
+ return pMem->u.Lock.R0Process == NIL_RTR0PROCESS
+ ? kernel_map
+ : &((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map;
+
+ case RTR0MEMOBJTYPE_RES_VIRT:
+ return pMem->u.ResVirt.R0Process == NIL_RTR0PROCESS
+ ? kernel_map
+ : &((struct proc *)pMem->u.ResVirt.R0Process)->p_vmspace->vm_map;
+
+ case RTR0MEMOBJTYPE_MAPPING:
+ return pMem->u.Mapping.R0Process == NIL_RTR0PROCESS
+ ? kernel_map
+ : &((struct proc *)pMem->u.Mapping.R0Process)->p_vmspace->vm_map;
+
+ default:
+ return NULL;
+ }
+}
+#endif
+
+
+int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+{
+ PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
+ int rc = B_OK;
+
+ switch (pMemHaiku->Core.enmType)
+ {
+ case RTR0MEMOBJTYPE_PAGE:
+ case RTR0MEMOBJTYPE_LOW:
+ case RTR0MEMOBJTYPE_CONT:
+ case RTR0MEMOBJTYPE_MAPPING:
+ case RTR0MEMOBJTYPE_PHYS:
+ case RTR0MEMOBJTYPE_PHYS_NC:
+ {
+ if (pMemHaiku->AreaId > -1)
+ rc = delete_area(pMemHaiku->AreaId);
+
+ AssertMsg(rc == B_OK, ("%#x", rc));
+ break;
+ }
+
+ case RTR0MEMOBJTYPE_LOCK:
+ {
+ team_id team = B_SYSTEM_TEAM;
+
+ if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+ team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
+
+ rc = unlock_memory_etc(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb, B_READ_DEVICE);
+ AssertMsg(rc == B_OK, ("%#x", rc));
+ break;
+ }
+
+ case RTR0MEMOBJTYPE_RES_VIRT:
+ {
+ team_id team = B_SYSTEM_TEAM;
+ if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+ team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
+
+ rc = vm_unreserve_address_range(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb);
+ AssertMsg(rc == B_OK, ("%#x", rc));
+ break;
+ }
+
+ default:
+ AssertMsgFailed(("enmType=%d\n", pMemHaiku->Core.enmType));
+ return VERR_INTERNAL_ERROR;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+static int rtR0MemObjNativeAllocArea(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
+ bool fExecutable, RTR0MEMOBJTYPE type, RTHCPHYS PhysHighest, size_t uAlignment)
+{
+ NOREF(fExecutable);
+
+ int rc;
+ void *pvMap = NULL;
+ const char *pszName = NULL;
+ uint32 addressSpec = B_ANY_KERNEL_ADDRESS;
+ uint32 fLock = ~0U;
+ LogFlowFunc(("ppMem=%p cb=%u, fExecutable=%s, type=%08x, PhysHighest=%RX64 uAlignment=%u\n", ppMem,(unsigned)cb,
+ fExecutable ? "true" : "false", type, PhysHighest,(unsigned)uAlignment));
+
+ switch (type)
+ {
+ case RTR0MEMOBJTYPE_PAGE:
+ pszName = "IPRT R0MemObj Alloc";
+ fLock = B_FULL_LOCK;
+ break;
+ case RTR0MEMOBJTYPE_LOW:
+ pszName = "IPRT R0MemObj AllocLow";
+ fLock = B_32_BIT_FULL_LOCK;
+ break;
+ case RTR0MEMOBJTYPE_CONT:
+ pszName = "IPRT R0MemObj AllocCont";
+ fLock = B_32_BIT_CONTIGUOUS;
+ break;
+#if 0
+ case RTR0MEMOBJTYPE_MAPPING:
+ pszName = "IPRT R0MemObj Mapping";
+ fLock = B_FULL_LOCK;
+ break;
+#endif
+ case RTR0MEMOBJTYPE_PHYS:
+ /** @todo alignment */
+ if (uAlignment != PAGE_SIZE)
+ return VERR_NOT_SUPPORTED;
+ /** @todo r=ramshankar: no 'break' here?? */
+ case RTR0MEMOBJTYPE_PHYS_NC:
+ pszName = "IPRT R0MemObj AllocPhys";
+ fLock = (PhysHighest < _4G ? B_LOMEM : B_32_BIT_CONTIGUOUS);
+ break;
+#if 0
+ case RTR0MEMOBJTYPE_LOCK:
+ break;
+#endif
+ default:
+ return VERR_INTERNAL_ERROR;
+ }
+
+ /* Create the object. */
+ PRTR0MEMOBJHAIKU pMemHaiku;
+ pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), type, NULL, cb);
+ if (RT_UNLIKELY(!pMemHaiku))
+ return VERR_NO_MEMORY;
+
+ rc = pMemHaiku->AreaId = create_area(pszName, &pvMap, addressSpec, cb, fLock, B_READ_AREA | B_WRITE_AREA);
+ if (pMemHaiku->AreaId >= 0)
+ {
+ physical_entry physMap[2];
+ pMemHaiku->Core.pv = pvMap; /* store start address */
+ switch (type)
+ {
+ case RTR0MEMOBJTYPE_CONT:
+ rc = get_memory_map(pvMap, cb, physMap, 2);
+ if (rc == B_OK)
+ pMemHaiku->Core.u.Cont.Phys = physMap[0].address;
+ break;
+
+ case RTR0MEMOBJTYPE_PHYS:
+ case RTR0MEMOBJTYPE_PHYS_NC:
+ rc = get_memory_map(pvMap, cb, physMap, 2);
+ if (rc == B_OK)
+ {
+ pMemHaiku->Core.u.Phys.PhysBase = physMap[0].address;
+ pMemHaiku->Core.u.Phys.fAllocated = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (rc >= B_OK)
+ {
+ *ppMem = &pMemHaiku->Core;
+ return VINF_SUCCESS;
+ }
+
+ delete_area(pMemHaiku->AreaId);
+ }
+
+ rtR0MemObjDelete(&pMemHaiku->Core);
+ return RTErrConvertFromHaikuKernReturn(rc);
+}
+
+
+int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+ return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_PAGE, 0 /* PhysHighest */, 0 /* uAlignment */);
+}
+
+
+int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+ return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_LOW, 0 /* PhysHighest */, 0 /* uAlignment */);
+}
+
+
+int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+ return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_CONT, 0 /* PhysHighest */, 0 /* uAlignment */);
+}
+
+int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+{
+ return rtR0MemObjNativeAllocArea(ppMem, cb, false, RTR0MEMOBJTYPE_PHYS, PhysHighest, uAlignment);
+}
+
+
+int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+{
+ return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE);
+}
+
+
+int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+{
+ AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
+ LogFlowFunc(("ppMem=%p Phys=%08x cb=%u uCachePolicy=%x\n", ppMem, Phys,(unsigned)cb, uCachePolicy));
+
+ /* Create the object. */
+ PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_PHYS, NULL, cb);
+ if (!pMemHaiku)
+ return VERR_NO_MEMORY;
+
+ /* There is no allocation here, it needs to be mapped somewhere first. */
+ pMemHaiku->AreaId = -1;
+ pMemHaiku->Core.u.Phys.fAllocated = false;
+ pMemHaiku->Core.u.Phys.PhysBase = Phys;
+ pMemHaiku->Core.u.Phys.uCachePolicy = uCachePolicy;
+ *ppMem = &pMemHaiku->Core;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker locking the memory in either kernel or user maps.
+ *
+ * @returns IPRT status code.
+ * @param ppMem Where to store the allocated memory object.
+ * @param pvStart The starting address.
+ * @param cb The size of the block.
+ * @param fAccess The mapping protection to apply.
+ * @param R0Process The process to map the memory to (use NIL_RTR0PROCESS
+ * for the kernel)
+ * @param fFlags Memory flags (B_READ_DEVICE indicates the memory is
+ * intended to be written from a "device").
+ */
+static int rtR0MemObjNativeLockInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvStart, size_t cb, uint32_t fAccess,
+ RTR0PROCESS R0Process, int fFlags)
+{
+ NOREF(fAccess);
+ int rc;
+ team_id TeamId = B_SYSTEM_TEAM;
+
+ LogFlowFunc(("ppMem=%p pvStart=%p cb=%u fAccess=%x R0Process=%d fFlags=%x\n", ppMem, pvStart, cb, fAccess, R0Process,
+ fFlags));
+
+ /* Create the object. */
+ PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_LOCK, pvStart, cb);
+ if (RT_UNLIKELY(!pMemHaiku))
+ return VERR_NO_MEMORY;
+
+ if (R0Process != NIL_RTR0PROCESS)
+ TeamId = (team_id)R0Process;
+ rc = lock_memory_etc(TeamId, pvStart, cb, fFlags);
+ if (rc == B_OK)
+ {
+ pMemHaiku->AreaId = -1;
+ pMemHaiku->Core.u.Lock.R0Process = R0Process;
+ *ppMem = &pMemHaiku->Core;
+ return VINF_SUCCESS;
+ }
+ rtR0MemObjDelete(&pMemHaiku->Core);
+ return RTErrConvertFromHaikuKernReturn(rc);
+}
+
+
+int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+{
+ return rtR0MemObjNativeLockInMap(ppMem, (void *)R3Ptr, cb, fAccess, R0Process, B_READ_DEVICE);
+}
+
+
+int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+{
+ return rtR0MemObjNativeLockInMap(ppMem, pv, cb, fAccess, NIL_RTR0PROCESS, B_READ_DEVICE);
+}
+
+
+#if 0
+/** @todo Reserve address space */
+/**
+ * Worker for the two virtual address space reservers.
+ *
+ * We're leaning on the examples provided by mmap and vm_mmap in vm_mmap.c here.
+ */
+static int rtR0MemObjNativeReserveInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
+ RTR0PROCESS R0Process)
+{
+ int rc;
+ team_id TeamId = B_SYSTEM_TEAM;
+
+ LogFlowFunc(("ppMem=%p pvFixed=%p cb=%u uAlignment=%u R0Process=%d\n", ppMem, pvFixed, (unsigned)cb, uAlignment, R0Process));
+
+ if (R0Process != NIL_RTR0PROCESS)
+ team = (team_id)R0Process;
+
+ /* Check that the specified alignment is supported. */
+ if (uAlignment > PAGE_SIZE)
+ return VERR_NOT_SUPPORTED;
+
+ /* Create the object. */
+ PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_RES_VIRT, NULL, cb);
+ if (!pMemHaiku)
+ return VERR_NO_MEMORY;
+
+ /* Ask the kernel to reserve the address range. */
+ //XXX: vm_reserve_address_range ?
+ return VERR_NOT_SUPPORTED;
+}
+#endif
+
+
+int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+{
+ return VERR_NOT_SUPPORTED;
+}
+
+
+int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+{
+ return VERR_NOT_SUPPORTED;
+}
+
+
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub)
+{
+ PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
+ PRTR0MEMOBJHAIKU pMemHaiku;
+ area_id area = -1;
+ void *pvMap = pvFixed;
+ uint32 uAddrSpec = B_EXACT_ADDRESS;
+ uint32 fProtect = 0;
+ int rc = VERR_MAP_FAILED;
+ AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
+ AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
+#if 0
+ /** @todo r=ramshankar: Wrong format specifiers, fix later! */
+ dprintf("%s(%p, %p, %p, %d, %x, %u, %u)\n", __FUNCTION__, ppMem, pMemToMap, pvFixed, uAlignment,
+ fProt, offSub, cbSub);
+#endif
+ /* Check that the specified alignment is supported. */
+ if (uAlignment > PAGE_SIZE)
+ return VERR_NOT_SUPPORTED;
+
+ /* We can't map anything to the first page, sorry. */
+ if (pvFixed == 0)
+ return VERR_NOT_SUPPORTED;
+
+ if (fProt & RTMEM_PROT_READ)
+ fProtect |= B_KERNEL_READ_AREA;
+ if (fProt & RTMEM_PROT_WRITE)
+ fProtect |= B_KERNEL_WRITE_AREA;
+
+ /*
+ * Either the object we map has an area associated with, which we can clone,
+ * or it's a physical address range which we must map.
+ */
+ if (pMemToMapHaiku->AreaId > -1)
+ {
+ if (pvFixed == (void *)-1)
+ uAddrSpec = B_ANY_KERNEL_ADDRESS;
+
+ rc = area = clone_area("IPRT R0MemObj MapKernel", &pvMap, uAddrSpec, fProtect, pMemToMapHaiku->AreaId);
+ LogFlow(("rtR0MemObjNativeMapKernel: clone_area uAddrSpec=%d fProtect=%x AreaId=%d rc=%d\n", uAddrSpec, fProtect,
+ pMemToMapHaiku->AreaId, rc));
+ }
+ else if (pMemToMapHaiku->Core.enmType == RTR0MEMOBJTYPE_PHYS)
+ {
+ /* map_physical_memory() won't let you choose where. */
+ if (pvFixed != (void *)-1)
+ return VERR_NOT_SUPPORTED;
+ uAddrSpec = B_ANY_KERNEL_ADDRESS;
+
+ rc = area = map_physical_memory("IPRT R0MemObj MapKernelPhys", (phys_addr_t)pMemToMapHaiku->Core.u.Phys.PhysBase,
+ pMemToMapHaiku->Core.cb, uAddrSpec, fProtect, &pvMap);
+ }
+ else
+ return VERR_NOT_SUPPORTED;
+
+ if (rc >= B_OK)
+ {
+ /* Create the object. */
+ pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), RTR0MEMOBJTYPE_MAPPING, pvMap,
+ pMemToMapHaiku->Core.cb);
+ if (RT_UNLIKELY(!pMemHaiku))
+ return VERR_NO_MEMORY;
+
+ pMemHaiku->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
+ pMemHaiku->Core.pv = pvMap;
+ pMemHaiku->AreaId = area;
+ *ppMem = &pMemHaiku->Core;
+ return VINF_SUCCESS;
+ }
+ rc = VERR_MAP_FAILED;
+
+ /** @todo finish the implementation. */
+
+ rtR0MemObjDelete(&pMemHaiku->Core);
+ return rc;
+}
+
+
+int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment,
+ unsigned fProt, RTR0PROCESS R0Process)
+{
+#if 0
+ /*
+ * Check for unsupported stuff.
+ */
+ AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
+ AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
+ if (uAlignment > PAGE_SIZE)
+ return VERR_NOT_SUPPORTED;
+
+ int rc;
+ PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
+ struct proc *pProc = (struct proc *)R0Process;
+ struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;
+
+ /* calc protection */
+ vm_prot_t ProtectionFlags = 0;
+ if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE)
+ ProtectionFlags = VM_PROT_NONE;
+ if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
+ ProtectionFlags |= VM_PROT_READ;
+ if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
+ ProtectionFlags |= VM_PROT_WRITE;
+ if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
+ ProtectionFlags |= VM_PROT_EXECUTE;
+
+ /* calc mapping address */
+ PROC_LOCK(pProc);
+ vm_offset_t AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA));
+ PROC_UNLOCK(pProc);
+
+ /* Insert the object in the map. */
+ rc = vm_map_find(pProcMap, /* Map to insert the object in */
+ NULL, /* Object to map */
+ 0, /* Start offset in the object */
+ &AddrR3, /* Start address IN/OUT */
+ pMemToMap->cb, /* Size of the mapping */
+ TRUE, /* Whether a suitable address should be searched for first */
+ ProtectionFlags, /* protection flags */
+ VM_PROT_ALL, /* Maximum protection flags */
+ 0); /* Copy on write */
+
+ /* Map the memory page by page into the destination map. */
+ if (rc == KERN_SUCCESS)
+ {
+ size_t cPages = pMemToMap->cb >> PAGE_SHIFT;;
+ pmap_t pPhysicalMap = pProcMap->pmap;
+ vm_offset_t AddrR3Dst = AddrR3;
+
+ if ( pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS
+ || pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS_NC
+ || pMemToMap->enmType == RTR0MEMOBJTYPE_PAGE)
+ {
+ /* Mapping physical allocations */
+ Assert(cPages == pMemToMapHaiku->u.Phys.cPages);
+
+ /* Insert the memory page by page into the mapping. */
+ for (uint32_t iPage = 0; iPage < cPages; iPage++)
+ {
+ vm_page_t pPage = pMemToMapHaiku->u.Phys.apPages[iPage];
+
+ MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
+ AddrR3Dst += PAGE_SIZE;
+ }
+ }
+ else
+ {
+ /* Mapping cont or low memory types */
+ vm_offset_t AddrToMap = (vm_offset_t)pMemToMap->pv;
+
+ for (uint32_t iPage = 0; iPage < cPages; iPage++)
+ {
+ vm_page_t pPage = PHYS_TO_VM_PAGE(vtophys(AddrToMap));
+
+ MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
+ AddrR3Dst += PAGE_SIZE;
+ AddrToMap += PAGE_SIZE;
+ }
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Create a mapping object for it.
+ */
+ PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU),
+ RTR0MEMOBJTYPE_MAPPING,
+ (void *)AddrR3,
+ pMemToMap->cb);
+ if (pMemHaiku)
+ {
+ Assert((vm_offset_t)pMemHaiku->Core.pv == AddrR3);
+ pMemHaiku->Core.u.Mapping.R0Process = R0Process;
+ *ppMem = &pMemHaiku->Core;
+ return VINF_SUCCESS;
+ }
+
+ rc = vm_map_remove(pProcMap, ((vm_offset_t)AddrR3), ((vm_offset_t)AddrR3) + pMemToMap->cb);
+ AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n"));
+ }
+#endif
+ return VERR_NOT_SUPPORTED;
+}
+
+
+int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+{
+ return VERR_NOT_SUPPORTED;
+}
+
+
+RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+{
+ PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
+ status_t rc;
+
+ /** @todo r=ramshankar: Validate objects */
+
+ LogFlow(("rtR0MemObjNativeGetPagePhysAddr: pMem=%p enmType=%x iPage=%u\n", pMem, pMemHaiku->Core.enmType,(unsigned)iPage));
+
+ switch (pMemHaiku->Core.enmType)
+ {
+ case RTR0MEMOBJTYPE_LOCK:
+ {
+ team_id TeamId = B_SYSTEM_TEAM;
+ physical_entry aPhysMap[2];
+ int32 cPhysMap = 2; /** @todo r=ramshankar: why not use RT_ELEMENTS? */
+
+ if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+ TeamId = (team_id)pMemHaiku->Core.u.Lock.R0Process;
+ void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
+
+ rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
+ if (rc < B_OK || cPhysMap < 1)
+ return NIL_RTHCPHYS;
+
+ return aPhysMap[0].address;
+ }
+
+#if 0
+ case RTR0MEMOBJTYPE_MAPPING:
+ {
+ vm_offset_t pb = (vm_offset_t)pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
+
+ if (pMemHaiku->Core.u.Mapping.R0Process != NIL_RTR0PROCESS)
+ {
+ struct proc *pProc = (struct proc *)pMemHaiku->Core.u.Mapping.R0Process;
+ struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;
+ pmap_t pPhysicalMap = pProcMap->pmap;
+
+ return pmap_extract(pPhysicalMap, pb);
+ }
+ return vtophys(pb);
+ }
+#endif
+ case RTR0MEMOBJTYPE_CONT:
+ return pMemHaiku->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
+
+ case RTR0MEMOBJTYPE_PHYS:
+ return pMemHaiku->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
+
+ case RTR0MEMOBJTYPE_LOW:
+ case RTR0MEMOBJTYPE_PAGE:
+ case RTR0MEMOBJTYPE_PHYS_NC:
+ {
+ team_id TeamId = B_SYSTEM_TEAM;
+ physical_entry aPhysMap[2];
+ int32 cPhysMap = 2; /** @todo r=ramshankar: why not use RT_ELEMENTS? */
+
+ void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
+ rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
+ if (rc < B_OK || cPhysMap < 1)
+ return NIL_RTHCPHYS;
+
+ return aPhysMap[0].address;
+ }
+
+ case RTR0MEMOBJTYPE_RES_VIRT:
+ default:
+ return NIL_RTHCPHYS;
+ }
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c
new file mode 100644
index 00000000..0d0af546
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c
@@ -0,0 +1,218 @@
+/* $Id: mp-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Multiprocessor, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+
+#include <iprt/mp.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/cpuset.h>
+#include "r0drv/mp-r0drv.h"
+
+
+RTDECL(RTCPUID) RTMpCpuId(void)
+{
+ return smp_get_current_cpu();
+}
+
+
+RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
+{
+ return idCpu < smp_get_num_cpus() ? (int)idCpu : -1;
+}
+
+
+RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
+{
+ return (unsigned)iCpu < smp_get_num_cpus() ? (RTCPUID)iCpu : NIL_RTCPUID;
+}
+
+
+RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
+{
+ return smp_get_num_cpus() - 1;
+}
+
+
+RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
+{
+ return idCpu < smp_get_num_cpus();
+}
+
+
+RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
+{
+ RTCPUID idCpu;
+
+ RTCpuSetEmpty(pSet);
+ idCpu = RTMpGetMaxCpuId();
+ do
+ {
+ if (RTMpIsCpuPossible(idCpu))
+ RTCpuSetAdd(pSet, idCpu);
+ } while (idCpu-- > 0);
+ return pSet;
+}
+
+
+RTDECL(RTCPUID) RTMpGetCount(void)
+{
+ return smp_get_num_cpus();
+}
+
+
+RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
+{
+ return idCpu < smp_get_num_cpus();
+ /** @todo: FixMe && !CPU_ABSENT(idCpu) */
+}
+
+
+RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
+{
+ RTCPUID idCpu;
+
+ RTCpuSetEmpty(pSet);
+ idCpu = RTMpGetMaxCpuId();
+ do
+ {
+ if (RTMpIsCpuOnline(idCpu))
+ RTCpuSetAdd(pSet, idCpu);
+ } while (idCpu-- > 0);
+
+ return pSet;
+}
+
+
+RTDECL(RTCPUID) RTMpGetOnlineCount(void)
+{
+ return smp_get_num_cpus();
+}
+
+
+/**
+ * Wrapper between the native Haiku per-cpu callback and PFNRTWORKER
+ * for the RTMpOnAll API.
+ *
+ * @param pvArg Pointer to the RTMPARGS package.
+ */
+static void rtmpOnAllHaikuWrapper(void *pvArg, int current)
+{
+ PRTMPARGS pArgs = (PRTMPARGS)pvArg;
+ pArgs->pfnWorker(current, pArgs->pvUser1, pArgs->pvUser2);
+}
+
+
+RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+ RTMPARGS Args;
+ Args.pfnWorker = pfnWorker;
+ Args.pvUser1 = pvUser1;
+ Args.pvUser2 = pvUser2;
+ Args.idCpu = NIL_RTCPUID;
+ Args.cHits = 0;
+ /* is _sync needed ? */
+ call_all_cpus_sync(rtmpOnAllHaikuWrapper, &Args);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Wrapper between the native Haiku per-cpu callback and PFNRTWORKER
+ * for the RTMpOnOthers API.
+ *
+ * @param pvArg Pointer to the RTMPARGS package.
+ */
+static void rtmpOnOthersHaikuWrapper(void *pvArg, int current)
+{
+ PRTMPARGS pArgs = (PRTMPARGS)pvArg;
+ RTCPUID idCpu = current;
+ if (pArgs->idCpu != idCpu)
+ pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+}
+
+
+RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+ /* Will panic if no rendezvousing cpus, so check up front. */
+ if (RTMpGetOnlineCount() > 1)
+ {
+ RTMPARGS Args;
+
+ Args.pfnWorker = pfnWorker;
+ Args.pvUser1 = pvUser1;
+ Args.pvUser2 = pvUser2;
+ Args.idCpu = RTMpCpuId();
+ Args.cHits = 0;
+ /* is _sync needed ? */
+ call_all_cpus_sync(rtmpOnOthersHaikuWrapper, &Args);
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Wrapper between the native Haiku per-cpu callback and PFNRTWORKER
+ * for the RTMpOnSpecific API.
+ *
+ * @param pvArg Pointer to the RTMPARGS package.
+ */
+static void rtmpOnSpecificHaikuWrapper(void *pvArg, int current)
+{
+ PRTMPARGS pArgs = (PRTMPARGS)pvArg;
+ RTCPUID idCpu = current;
+ if (pArgs->idCpu == idCpu)
+ {
+ pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+ ASMAtomicIncU32(&pArgs->cHits);
+ }
+}
+
+
+RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+ RTMPARGS Args;
+
+ /* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
+ if (!RTMpIsCpuOnline(idCpu))
+ return VERR_CPU_NOT_FOUND;
+
+ Args.pfnWorker = pfnWorker;
+ Args.pvUser1 = pvUser1;
+ Args.pvUser2 = pvUser2;
+ Args.idCpu = idCpu;
+ Args.cHits = 0;
+ /* is _sync needed ? */
+ call_all_cpus_sync(rtmpOnSpecificHaikuWrapper, &Args);
+ return Args.cHits == 1
+ ? VINF_SUCCESS
+ : VERR_CPU_NOT_FOUND;
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c
new file mode 100644
index 00000000..a3b6a5c8
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c
@@ -0,0 +1,46 @@
+/* $Id: process-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Process, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/process.h>
+
+
+RTDECL(RTPROCESS) RTProcSelf(void)
+{
+ return getpid();
+}
+
+
+RTR0DECL(RTR0PROCESS) RTR0ProcHandleSelf(void)
+{
+ return (RTR0PROCESS)(team_id)getpid();
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c
new file mode 100644
index 00000000..9914262f
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c
@@ -0,0 +1,264 @@
+/* $Id: semevent-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Single Release Event Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/lockvalidator.h>
+#include <iprt/mem.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Haiku event semaphore.
+ */
+typedef struct RTSEMEVENTINTERNAL
+{
+ /** Magic value (RTSEMEVENT_MAGIC). */
+ uint32_t volatile u32Magic;
+ /** Reference counter. */
+ uint32_t volatile cRefs;
+ /** The semaphore Id. */
+ sem_id SemId;
+} RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
+
+
+RTDECL(int) RTSemEventCreate(PRTSEMEVENT phEventSem)
+{
+ return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
+}
+
+
+RTDECL(int) RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)
+{
+ AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
+ AssertReturn(!(fFlags & ~(RTSEMEVENT_FLAGS_NO_LOCK_VAL | RTSEMEVENT_FLAGS_BOOTSTRAP_HACK)), VERR_INVALID_PARAMETER);
+ Assert(!(fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK) || (fFlags & RTSEMEVENT_FLAGS_NO_LOCK_VAL));
+ AssertPtrReturn(phEventSem, VERR_INVALID_POINTER);
+
+ PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAllocZ(sizeof(*pThis));
+ if (!pThis)
+ return VERR_NO_MEMORY;
+
+ pThis->u32Magic = RTSEMEVENT_MAGIC;
+ pThis->cRefs = 1;
+ pThis->SemId = create_sem(0, "IPRT Semaphore Event");
+ if (pThis->SemId >= B_OK)
+ {
+ set_sem_owner(pThis->SemId, B_SYSTEM_TEAM);
+ *phEventSem = pThis;
+ return VINF_SUCCESS;
+ }
+
+ RTMemFree(pThis);
+ return VERR_TOO_MANY_SEMAPHORES; /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+/**
+ * Retains a reference to the event semaphore.
+ *
+ * @param pThis The event semaphore.
+ */
+DECLINLINE(void) rtR0SemEventHkuRetain(PRTSEMEVENTINTERNAL pThis)
+{
+ uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ Assert(cRefs < 100000); NOREF(cRefs);
+}
+
+
+/**
+ * Releases a reference to the event semaphore.
+ *
+ * @param pThis The event semaphore.
+ */
+DECLINLINE(void) rtR0SemEventHkuRelease(PRTSEMEVENTINTERNAL pThis)
+{
+ if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
+ RTMemFree(pThis);
+}
+
+
+RTDECL(int) RTSemEventDestroy(RTSEMEVENT hEventSem)
+{
+ /*
+ * Validate input.
+ */
+ PRTSEMEVENTINTERNAL pThis = hEventSem;
+ if (pThis == NIL_RTSEMEVENT)
+ return VINF_SUCCESS;
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+ Assert(pThis->cRefs > 0);
+
+ /*
+ * Invalidate it and delete the semaphore to unblock everyone.
+ */
+ ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENT_MAGIC);
+ delete_sem(pThis->SemId);
+ pThis->SemId = -1;
+ rtR0SemEventHkuRelease(pThis);
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTSemEventSignal(RTSEMEVENT hEventSem)
+{
+ /*
+ * Validate input.
+ */
+ PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+ rtR0SemEventHkuRetain(pThis);
+
+ /*
+ * Signal the event object.
+ * We must use B_DO_NOT_RESCHEDULE since we are being used from an irq handler.
+ */
+ release_sem_etc(pThis->SemId, 1, B_DO_NOT_RESCHEDULE);
+ rtR0SemEventHkuRelease(pThis);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for RTSemEventWaitEx and RTSemEventWaitExDebug.
+ *
+ * @returns VBox status code.
+ * @param pThis The event semaphore.
+ * @param fFlags See RTSemEventWaitEx.
+ * @param uTimeout See RTSemEventWaitEx.
+ * @param pSrcPos The source code position of the wait.
+ */
+static int rtR0SemEventWait(PRTSEMEVENTINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
+ PCRTLOCKVALSRCPOS pSrcPos)
+{
+ status_t status;
+ int rc;
+ int32 flags = 0;
+ bigtime_t timeout; /* in microseconds */
+
+ /*
+ * Validate the input.
+ */
+ AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+ AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+
+ if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+ timeout = B_INFINITE_TIMEOUT;
+ else
+ {
+ if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
+ timeout = uTimeout / 1000;
+ else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+ timeout = uTimeout * 1000;
+ else
+ return VERR_INVALID_PARAMETER;
+
+ if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+ flags |= B_RELATIVE_TIMEOUT;
+ else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+ flags |= B_ABSOLUTE_TIMEOUT;
+ else
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
+ flags |= B_CAN_INTERRUPT;
+ // likely not:
+ //else
+ // flags |= B_KILL_CAN_INTERRUPT;
+
+ rtR0SemEventHkuRetain(pThis);
+
+ status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
+
+ switch (status)
+ {
+ case B_OK:
+ rc = VINF_SUCCESS;
+ break;
+ case B_BAD_SEM_ID:
+ rc = VERR_SEM_DESTROYED;
+ break;
+ case B_INTERRUPTED:
+ rc = VERR_INTERRUPTED;
+ break;
+ case B_WOULD_BLOCK:
+ /* fallthrough ? */
+ case B_TIMED_OUT:
+ rc = VERR_TIMEOUT;
+ break;
+ default:
+ rc = RTErrConvertFromHaikuKernReturn(status);
+ break;
+ }
+
+ rtR0SemEventHkuRelease(pThis);
+ return rc;
+}
+
+
+RTDECL(int) RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+ return rtR0SemEventWait(hEventSem, fFlags, uTimeout, NULL);
+#else
+ RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+ return rtR0SemEventWait(hEventSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitEx);
+
+
+RTDECL(int) RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+ RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+ return rtR0SemEventWait(hEventSem, fFlags, uTimeout, &SrcPos);
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitExDebug);
+
+
+RTDECL(uint32_t) RTSemEventGetResolution(void)
+{
+ /* At least that's what the API supports. */
+ return 1000;
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c
new file mode 100644
index 00000000..3179fc9b
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c
@@ -0,0 +1,291 @@
+/* $Id: semeventmulti-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/lockvalidator.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Haiku multiple release event semaphore.
+ */
+typedef struct RTSEMEVENTMULTIINTERNAL
+{
+ /** Magic value (RTSEMEVENTMULTI_MAGIC). */
+ uint32_t volatile u32Magic;
+ /** Reference counter. */
+ uint32_t volatile cRefs;
+ /** The semaphore Id. */
+ sem_id SemId;
+} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
+
+
+RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
+{
+ return RTSemEventMultiCreateEx(phEventMultiSem, 0 /* fFlags */, NIL_RTLOCKVALCLASS, NULL);
+}
+
+
+RTDECL(int) RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
+ const char *pszNameFmt, ...)
+{
+ PRTSEMEVENTMULTIINTERNAL pThis;
+
+ AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
+ pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
+ if (!pThis)
+ return VERR_NO_MEMORY;
+
+ pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
+ pThis->cRefs = 1;
+ pThis->SemId = create_sem(0, "IPRT Semaphore Event Multi");
+ if (pThis->SemId < B_OK)
+ {
+ set_sem_owner(pThis->SemId, B_SYSTEM_TEAM);
+ *phEventMultiSem = pThis;
+ return VINF_SUCCESS;
+ }
+
+ RTMemFree(pThis);
+ return VERR_TOO_MANY_SEMAPHORES; /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+/**
+ * Retain a reference to the semaphore.
+ *
+ * @param pThis The semaphore.
+ */
+DECLINLINE(void) rtR0SemEventMultiHkuRetain(PRTSEMEVENTMULTIINTERNAL pThis)
+{
+ uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ Assert(cRefs && cRefs < 100000);
+}
+
+
+/**
+ * Release a reference, destroy the thing if necessary.
+ *
+ * @param pThis The semaphore.
+ */
+DECLINLINE(void) rtR0SemEventMultiHkuRelease(PRTSEMEVENTMULTIINTERNAL pThis)
+{
+ if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
+ {
+ Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC);
+ RTMemFree(pThis);
+ }
+}
+
+
+RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
+{
+ /*
+ * Validate input.
+ */
+ PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+ if (pThis == NIL_RTSEMEVENTMULTI)
+ return VINF_SUCCESS;
+ AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+ Assert(pThis->cRefs > 0);
+
+ /*
+ * Invalidate it and signal the object just in case.
+ */
+ ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC);
+ delete_sem(pThis->SemId);
+ pThis->SemId = -1;
+ rtR0SemEventMultiHkuRelease(pThis);
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
+{
+ /*
+ * Validate input.
+ */
+ PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+ if (!pThis)
+ return VERR_INVALID_PARAMETER;
+ AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+ rtR0SemEventMultiHkuRetain(pThis);
+
+ /*
+ * Signal the event object.
+ * We must use B_DO_NOT_RESCHEDULE since we are being used from an irq handler.
+ */
+ release_sem_etc(pThis->SemId, 1, B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
+ rtR0SemEventMultiHkuRelease(pThis);
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)
+{
+ /*
+ * Validate input.
+ */
+ PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+ if (!pThis)
+ return VERR_INVALID_PARAMETER;
+ AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+ rtR0SemEventMultiHkuRetain(pThis);
+
+ /*
+ * Reset it.
+ */
+ //FIXME: what should I do ???
+ // delete_sem + create_sem ??
+ rtR0SemEventMultiHkuRelease(pThis);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.
+ *
+ * @returns VBox status code.
+ * @param pThis The event semaphore.
+ * @param fFlags See RTSemEventMultiWaitEx.
+ * @param uTimeout See RTSemEventMultiWaitEx.
+ * @param pSrcPos The source code position of the wait.
+ */
+static int rtR0SemEventMultiHkuWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
+ PCRTLOCKVALSRCPOS pSrcPos)
+{
+ status_t status;
+ int rc;
+ int32 flags = 0;
+ bigtime_t timeout; /* in microseconds */
+
+ /*
+ * Validate the input.
+ */
+ AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+ AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+
+ if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+ timeout = B_INFINITE_TIMEOUT;
+ else
+ {
+ if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
+ timeout = uTimeout / 1000;
+ else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+ timeout = uTimeout * 1000;
+ else
+ return VERR_INVALID_PARAMETER;
+
+ if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+ flags |= B_RELATIVE_TIMEOUT;
+ else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+ flags |= B_ABSOLUTE_TIMEOUT;
+ else
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
+ flags |= B_CAN_INTERRUPT;
+ // likely not:
+ //else
+ // flags |= B_KILL_CAN_INTERRUPT;
+
+ rtR0SemEventMultiHkuRetain(pThis);
+
+ status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
+
+ switch (status)
+ {
+ case B_OK:
+ rc = VINF_SUCCESS;
+ break;
+ case B_BAD_SEM_ID:
+ rc = VERR_SEM_DESTROYED;
+ break;
+ case B_INTERRUPTED:
+ rc = VERR_INTERRUPTED;
+ break;
+ case B_WOULD_BLOCK:
+ /* fallthrough? */
+ case B_TIMED_OUT:
+ rc = VERR_TIMEOUT;
+ break;
+ default:
+ rc = RTErrConvertFromHaikuKernReturn(status);
+ break;
+ }
+
+ rtR0SemEventMultiHkuRelease(pThis);
+ return rc;
+}
+
+
+RTDECL(int) RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+ return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, NULL);
+#else
+ RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+ return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitEx);
+
+
+RTDECL(int) RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+ RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+ return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitExDebug);
+
+
+RTDECL(uint32_t) RTSemEventMultiGetResolution(void)
+{
+ /* At least that's what the API supports. */
+ return 1000;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiGetResolution);
+
diff --git a/src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c
new file mode 100644
index 00000000..c34189cb
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c
@@ -0,0 +1,120 @@
+/* $Id: semfastmutex-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Fast Mutex Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+
+#include <iprt/semaphore.h>
+#include <iprt/err.h>
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Wrapper for the Haiku (sleep) mutex.
+ */
+typedef struct RTSEMFASTMUTEXINTERNAL
+{
+ /** Magic value (RTSEMFASTMUTEX_MAGIC). */
+ uint32_t u32Magic;
+ /** A good old Benaphore. */
+ vint32 BenId;
+ sem_id SemId;
+} RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
+
+
+RTDECL(int) RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx)
+{
+ AssertCompile(sizeof(RTSEMFASTMUTEXINTERNAL) > sizeof(void *));
+ AssertPtrReturn(phFastMtx, VERR_INVALID_POINTER);
+
+ PRTSEMFASTMUTEXINTERNAL pThis = (PRTSEMFASTMUTEXINTERNAL)RTMemAllocZ(sizeof(*pThis));
+ if (RT_UNLIKELY(!pThis))
+ return VERR_NO_MEMORY;
+
+ pThis->u32Magic = RTSEMFASTMUTEX_MAGIC;
+ pThis->BenId = 0;
+ pThis->SemId = create_sem(0, "IPRT Fast Mutex Semaphore");
+ if (pThis->SemId >= B_OK)
+ {
+ *phFastMtx = pThis;
+ return VINF_SUCCESS;
+ }
+ RTMemFree(pThis);
+ return VERR_TOO_MANY_SEMAPHORES; /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+RTDECL(int) RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx)
+{
+ PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+ if (pThis == NIL_RTSEMFASTMUTEX)
+ return VINF_SUCCESS;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+ ASMAtomicWriteU32(&pThis->u32Magic, RTSEMFASTMUTEX_MAGIC_DEAD);
+ delete_sem(pThis->SemId);
+ RTMemFree(pThis);
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx)
+{
+ PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+ if (atomic_add(&pThis->BenId, 1) > 0)
+ acquire_sem(pThis->SemId);
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
+{
+ PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+ if (atomic_add(&pThis->BenId, -1) > 1)
+ release_sem(pThis->SemId);
+
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c
new file mode 100644
index 00000000..4f4f68a8
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c
@@ -0,0 +1,233 @@
+/* $Id: semmutex-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Mutex Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/thread.h>
+#include <iprt/time.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Wrapper for the Haiku (sleep) mutex.
+ */
+/* XXX: not optimal, maybe should use the (private)
+ kernel recursive_lock ? (but it's not waitable) */
+typedef struct RTSEMMUTEXINTERNAL
+{
+ /** Magic value (RTSEMMUTEX_MAGIC). */
+ uint32_t u32Magic;
+ /** Kernel semaphore. */
+ sem_id SemId;
+ /** Current holder */
+ volatile thread_id OwnerId;
+ /** Recursion count */
+ int32 cRecursion;
+} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
+
+
+RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
+{
+ AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
+ AssertPtrReturn(phMutexSem, VERR_INVALID_POINTER);
+
+ PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAllocZ(sizeof(*pThis));
+ if (RT_UNLIKELY(!pThis))
+ return VERR_NO_MEMORY;
+
+ pThis->u32Magic = RTSEMMUTEX_MAGIC;
+ pThis->SemId = create_sem(0, "IPRT Mutex Semaphore");
+ if (pThis->SemId < B_OK)
+ {
+ pThis->OwnerId = -1;
+ pThis->cRecursion = 0;
+ *phMutexSem = pThis;
+ return VINF_SUCCESS;
+ }
+ RTMemFree(pThis);
+ return VERR_TOO_MANY_SEMAPHORES; /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMutexSem)
+{
+ PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+ if (pThis == NIL_RTSEMMUTEX)
+ return VINF_SUCCESS;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+ AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
+
+ delete_sem(pThis->SemId);
+ RTMemFree(pThis);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker function for acquiring the mutex.
+ *
+ * @param hMutexSem The mutex object.
+ * @param fFlags Mutex flags (see RTSEMWAIT_FLAGS_*)
+ * @param uTimeout Timeout in units specified by the flags.
+ *
+ * @return IPRT status code.
+ */
+static int rtSemMutexRequestEx(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout)
+{
+ PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+ int rc;
+ status_t status;
+ int32 flags = 0;
+ bigtime_t timeout; /* in microseconds */
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+ if (pThis->OwnerId == find_thread(NULL))
+ {
+ pThis->OwnerId++;
+ return VINF_SUCCESS;
+ }
+
+ if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+ timeout = B_INFINITE_TIMEOUT;
+ else
+ {
+ if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
+ timeout = uTimeout / 1000;
+ else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+ timeout = uTimeout * 1000;
+ else
+ return VERR_INVALID_PARAMETER;
+
+ if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+ flags |= B_RELATIVE_TIMEOUT;
+ else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+ flags |= B_ABSOLUTE_TIMEOUT;
+ else
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
+ flags |= B_CAN_INTERRUPT;
+
+ status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
+
+ switch (status)
+ {
+ case B_OK:
+ rc = VINF_SUCCESS;
+ pThis->cRecursion = 1;
+ pThis->OwnerId = find_thread(NULL);
+ break;
+ case B_BAD_SEM_ID:
+ rc = VERR_SEM_DESTROYED;
+ break;
+ case B_INTERRUPTED:
+ rc = VERR_INTERRUPTED;
+ break;
+ case B_WOULD_BLOCK:
+ /* fallthrough? */
+ case B_TIMED_OUT:
+ rc = VERR_TIMEOUT;
+ break;
+ default:
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+
+ return rc;
+}
+
+
+RTDECL(int) RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
+{
+ return rtSemMutexRequestEx(hMutexSem, RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS, cMillies);
+}
+
+
+RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+ return RTSemMutexRequest(hMutexSem, cMillies);
+}
+
+
+RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
+{
+ return rtSemMutexRequestEx(hMutexSem, RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_MILLISECS, cMillies);
+}
+
+
+RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+ return RTSemMutexRequestNoResume(hMutexSem, cMillies);
+}
+
+
+RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem)
+{
+ PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+ if (pThis->OwnerId != find_thread(NULL))
+ return VERR_INVALID_HANDLE;
+
+ if (--pThis->cRecursion == 0)
+ {
+ pThis->OwnerId == -1;
+ release_sem(pThis->SemId);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem)
+{
+ PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+ AssertPtrReturn(pThis, false);
+ AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), false);
+
+ return pThis->OwnerId != -1;
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c
new file mode 100644
index 00000000..6ffed171
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c
@@ -0,0 +1,146 @@
+/* $Id: spinlock-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Spinlocks, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/spinlock.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+#include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/thread.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Wrapper for the KSPIN_LOCK type.
+ */
+typedef struct RTSPINLOCKINTERNAL
+{
+ /** Spinlock magic value (RTSPINLOCK_MAGIC). */
+ uint32_t volatile u32Magic;
+ /** Spinlock creation flags */
+ uint32_t fFlags;
+ /** Saved interrupt CPU status. */
+ cpu_status volatile fIntSaved;
+ /** The Haiku spinlock structure. */
+ spinlock hSpinLock;
+} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
+
+
+
+RTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName)
+{
+ RT_ASSERT_PREEMPTIBLE();
+ NOREF(pszName);
+
+ /*
+ * Allocate.
+ */
+ AssertCompile(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *));
+ PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAllocZ(sizeof(*pSpinlockInt));
+ if (RT_UNLIKELY(!pSpinlockInt))
+ return VERR_NO_MEMORY;
+
+ /*
+ * Initialize & return.
+ */
+ pSpinlockInt->u32Magic = RTSPINLOCK_MAGIC;
+ pSpinlockInt->fFlags = fFlags;
+ pSpinlockInt->fIntSaved = 0;
+ B_INITIALIZE_SPINLOCK(&pSpinlockInt->hSpinLock);
+
+ *pSpinlock = pSpinlockInt;
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
+{
+ /*
+ * Validate input.
+ */
+ PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
+ if (RT_UNLIKELY(!pSpinlockInt))
+ return VERR_INVALID_PARAMETER;
+ AssertMsgReturn(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
+ ("Invalid spinlock %p magic=%#x\n", pSpinlockInt, pSpinlockInt->u32Magic),
+ VERR_INVALID_PARAMETER);
+
+ /*
+ * Make the lock invalid and release the memory.
+ */
+ ASMAtomicIncU32(&pSpinlockInt->u32Magic);
+
+ B_INITIALIZE_SPINLOCK(&pSpinlockInt->hSpinLock);
+
+ RTMemFree(pSpinlockInt);
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
+{
+ PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
+ AssertPtr(pSpinlockInt);
+ Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
+
+ /* Haiku cannot take spinlocks without disabling interrupts. Ignore our spinlock creation flags. */
+ pSpinlockInt->fIntSaved = disable_interrupts();
+ acquire_spinlock(&pSpinlockInt->hSpinLock);
+}
+
+
+RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
+{
+ PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
+ AssertPtr(pSpinlockInt);
+ Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
+
+ release_spinlock(&pSpinlockInt->hSpinLock);
+ restore_interrupts(pSpinlockInt->fIntSaved);
+}
+
+
+RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock)
+{
+ if (!(Spinlock->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE))
+ RTAssertMsg2("RTSpinlockReleaseNoInts: p=%p (magic=%#x)\n", Spinlock, Spinlock->u32Magic);
+ RTSpinlockRelease(Spinlock);
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h b/src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h
new file mode 100644
index 00000000..d75a163b
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h
@@ -0,0 +1,114 @@
+/* $Id: the-haiku-kernel.h $ */
+/** @file
+ * IPRT - Include all necessary headers for the Haiku kernel.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___the_haiku_kernel_h
+#define ___the_haiku_kernel_h
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include <stdlib.h>
+
+#include <OS.h>
+#include <KernelExport.h>
+
+#include <iprt/cdefs.h>
+#include <iprt/err.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/* headers/private/kernel/smp.h */
+
+extern int32 smp_get_num_cpus(void);
+extern int32 smp_get_current_cpu(void);
+
+/* headers/private/kernel/vm/vm.h */
+extern status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);
+extern status_t vm_reserve_address_range(team_id team, void **_address, uint32 addressSpec, addr_t size, uint32 flags);
+extern area_id vm_clone_area(team_id team, const char *name, void **address, uint32 addressSpec, uint32 protection,
+ uint32 mapping, area_id sourceArea, bool kernel);
+
+/* headers/private/kernel/thread_type.h */
+
+extern spinlock gThreadSpinlock;
+#define GRAB_THREAD_LOCK() acquire_spinlock(&gThreadSpinlock)
+#define RELEASE_THREAD_LOCK() release_spinlock(&gThreadSpinlock)
+typedef struct
+{
+ int32 flags; /* summary of events relevant in interrupt handlers (signals pending, user debugging
+ enabled, etc.) */
+#if 0
+ Thread *all_next;
+ Thread *team_next;
+ Thread *queue_next; /* i.e. run queue, release queue, etc. */
+ timer alarm;
+ thread_id id;
+ char name[B_OS_NAME_LENGTH];
+ int32 priority;
+ int32 next_priority;
+ int32 io_priority;
+ int32 state;
+ int32 next_state;
+#endif
+ // and a lot more...
+} Thread;
+
+/* headers/private/kernel/thread.h */
+
+extern Thread* thread_get_thread_struct(thread_id id);
+extern Thread* thread_get_thread_struct_locked(thread_id id);
+
+extern void thread_yield(bool force);
+
+RT_C_DECLS_END
+
+/**
+ * Convert from Haiku kernel return code to IPRT status code.
+ * @todo put this where it belongs! (i.e. in a separate file and prototype in iprt/err.h)
+ * Or as generic call since it's not r0 specific.
+ */
+DECLINLINE(int) RTErrConvertFromHaikuKernReturn(status_t rc)
+{
+ switch (rc)
+ {
+ case B_OK: return VINF_SUCCESS;
+ case B_BAD_SEM_ID: return VERR_SEM_ERROR;
+ case B_NO_MORE_SEMS: return VERR_TOO_MANY_SEMAPHORES;
+ case B_BAD_THREAD_ID: return VERR_INVALID_PARAMETER;
+ case B_NO_MORE_THREADS: return VERR_MAX_THRDS_REACHED;
+ case B_BAD_TEAM_ID: return VERR_INVALID_PARAMETER;
+ case B_NO_MORE_TEAMS: return VERR_MAX_PROCS_REACHED;
+ //default: return VERR_GENERAL_FAILURE;
+ /** POSIX Errors are defined as a subset of system errors. */
+ default: return RTErrConvertFromErrno(rc);
+ }
+}
+
+#endif /* ___the_haiku_kernel_h */
+
diff --git a/src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c
new file mode 100644
index 00000000..97766d3f
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c
@@ -0,0 +1,127 @@
+/* $Id: thread-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Threads, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/thread.h>
+
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+#include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mp.h>
+
+
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
+{
+ return (RTNATIVETHREAD)find_thread(NULL);
+}
+
+
+RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
+{
+ RT_ASSERT_PREEMPTIBLE();
+ snooze((bigtime_t)cMillies * 1000);
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(bool) RTThreadYield(void)
+{
+ RT_ASSERT_PREEMPTIBLE();
+ //FIXME
+ //snooze(0);
+ thread_yield(true);
+ return true; /* this is fishy */
+}
+
+
+RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread)
+{
+ Assert(hThread == NIL_RTTHREAD);
+
+ //XXX: can't do this, it might actually be held by another cpu
+ //return !B_SPINLOCK_IS_LOCKED(&gThreadSpinlock);
+ return ASMIntAreEnabled(); /** @todo find a better way. */
+}
+
+
+RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
+{
+ Assert(hThread == NIL_RTTHREAD);
+ /** @todo check if Thread::next_priority or
+ * cpu_ent::invoke_scheduler could do. */
+ return false;
+}
+
+
+RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
+{
+ /* RTThreadPreemptIsPending is not reliable yet. */
+ return false;
+}
+
+
+RTDECL(bool) RTThreadPreemptIsPossible(void)
+{
+ /* yes, kernel preemption is possible. */
+ return true;
+}
+
+
+RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
+{
+ AssertPtr(pState);
+ Assert(pState->uOldCpuState == 0);
+
+ pState->uOldCpuState = (uint32_t)disable_interrupts();
+ RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
+}
+
+
+RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
+{
+ AssertPtr(pState);
+
+ RT_ASSERT_PREEMPT_CPUID_RESTORE(pState);
+ restore_interrupts((cpu_status)pState->uOldCpuState);
+ pState->uOldCpuState = 0;
+}
+
+
+RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
+{
+ Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
+ /** @todo Implement RTThreadIsInInterrupt. Required for guest
+ * additions! */
+ return !ASMIntAreEnabled();
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c
new file mode 100644
index 00000000..f4c4a471
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c
@@ -0,0 +1,131 @@
+/* $Id: thread2-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Threads (Part 2), Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/thread.h>
+
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+#include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include "internal/thread.h"
+
+
+int rtThreadNativeInit(void)
+{
+ /* No TLS in Ring-0. :-/ */
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(RTTHREAD) RTThreadSelf(void)
+{
+ return rtThreadGetByNative((RTNATIVETHREAD)find_thread(NULL));
+}
+
+
+int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+{
+ int32 iPriority;
+ status_t status;
+
+ /*
+ * Convert the priority type to native priorities.
+ * (This is quite naive but should be ok.)
+ */
+ switch (enmType)
+ {
+ case RTTHREADTYPE_INFREQUENT_POLLER: iPriority = B_LOWEST_ACTIVE_PRIORITY; break;
+ case RTTHREADTYPE_EMULATION: iPriority = B_LOW_PRIORITY; break;
+ case RTTHREADTYPE_DEFAULT: iPriority = B_NORMAL_PRIORITY; break;
+ case RTTHREADTYPE_MSG_PUMP: iPriority = B_DISPLAY_PRIORITY; break;
+ case RTTHREADTYPE_IO: iPriority = B_URGENT_DISPLAY_PRIORITY; break;
+ case RTTHREADTYPE_TIMER: iPriority = B_REAL_TIME_DISPLAY_PRIORITY; break;
+ default:
+ AssertMsgFailed(("enmType=%d\n", enmType));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ status = set_thread_priority((thread_id)pThread->Core.Key, iPriority);
+
+ return RTErrConvertFromHaikuKernReturn(status);
+}
+
+
+int rtThreadNativeAdopt(PRTTHREADINT pThread)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+void rtThreadNativeDestroy(PRTTHREADINT pThread)
+{
+ NOREF(pThread);
+}
+
+
+/**
+ * Native kernel thread wrapper function.
+ *
+ * This will forward to rtThreadMain and do termination upon return.
+ *
+ * @param pvArg Pointer to the argument package.
+ * @param Ignored Wait result, which we ignore.
+ */
+static status_t rtThreadNativeMain(void *pvArg)
+{
+ const thread_id Self = find_thread(NULL);
+ PRTTHREADINT pThread = (PRTTHREADINT)pvArg;
+
+ int rc = rtThreadMain(pThread, (RTNATIVETHREAD)Self, &pThread->szName[0]);
+
+ if (rc < 0)
+ return RTErrConvertFromHaikuKernReturn(rc);
+ return rc;
+}
+
+
+int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+{
+ thread_id NativeThread;
+ RT_ASSERT_PREEMPTIBLE();
+
+ NativeThread = spawn_kernel_thread(rtThreadNativeMain, pThreadInt->szName, B_NORMAL_PRIORITY, pThreadInt);
+ if (NativeThread >= B_OK)
+ {
+ resume_thread(NativeThread);
+ *pNativeThread = (RTNATIVETHREAD)NativeThread;
+ return VINF_SUCCESS;
+ }
+ return RTErrConvertFromHaikuKernReturn(NativeThread);
+}
+
diff --git a/src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c b/src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c
new file mode 100644
index 00000000..889ac193
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c
@@ -0,0 +1,79 @@
+/* $Id: time-r0drv-haiku.c $ */
+/** @file
+ * IPRT - Time, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_TIME
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/time.h>
+
+#include <iprt/asm.h>
+
+
+DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
+{
+ return system_time() * 1000;
+}
+
+
+DECLINLINE(uint64_t) rtTimeGetSystemMilliTS(void)
+{
+ return system_time() / 1000;
+}
+
+
+RTDECL(uint64_t) RTTimeNanoTS(void)
+{
+ return rtTimeGetSystemNanoTS();
+}
+
+
+RTDECL(uint64_t) RTTimeMilliTS(void)
+{
+ return rtTimeGetSystemMilliTS();
+}
+
+
+RTDECL(uint64_t) RTTimeSystemNanoTS(void)
+{
+ return rtTimeGetSystemNanoTS();
+}
+
+
+RTDECL(uint64_t) RTTimeSystemMilliTS(void)
+{
+ return rtTimeGetSystemMilliTS();
+}
+
+
+RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
+{
+ return RTTimeSpecSetNano(pTime, real_time_clock_usecs() * 1000);
+}
+
diff --git a/src/VBox/Runtime/r0drv/initterm-r0drv.cpp b/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
index 09929142..db963feb 100644
--- a/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
+++ b/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -64,6 +64,7 @@ static int32_t volatile g_crtR0Users = 0;
RTR0DECL(int) RTR0Init(unsigned fReserved)
{
int rc;
+ uint32_t cNewUsers;
Assert(fReserved == 0);
RT_ASSERT_PREEMPTIBLE();
@@ -72,8 +73,14 @@ RTR0DECL(int) RTR0Init(unsigned fReserved)
* We rely on the module loader to ensure that there are no
* initialization races should two modules share the IPRT.
*/
- if (ASMAtomicIncS32(&g_crtR0Users) != 1)
- return VINF_SUCCESS;
+ cNewUsers = ASMAtomicIncS32(&g_crtR0Users);
+ if (cNewUsers != 1)
+ {
+ if (cNewUsers > 1)
+ return VINF_SUCCESS;
+ ASMAtomicDecS32(&g_crtR0Users);
+ return VERR_INTERNAL_ERROR_3;
+ }
rc = rtR0InitNative();
if (RT_SUCCESS(rc))
@@ -126,6 +133,8 @@ RTR0DECL(void) RTR0Term(void)
Assert(cNewUsers >= 0);
if (cNewUsers == 0)
rtR0Term();
+ else if (cNewUsers < 0)
+ ASMAtomicIncS32(&g_crtR0Users);
}
RT_EXPORT_SYMBOL(RTR0Term);
@@ -134,7 +143,9 @@ RT_EXPORT_SYMBOL(RTR0Term);
RTR0DECL(void) RTR0TermForced(void)
{
RT_ASSERT_PREEMPTIBLE();
+
AssertMsg(g_crtR0Users == 1, ("%d\n", g_crtR0Users));
+ ASMAtomicWriteS32(&g_crtR0Users, 0);
rtR0Term();
}
diff --git a/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
index 144d637e..c34f8543 100644
--- a/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
index 2f597651..21e124bd 100644
--- a/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -173,7 +173,7 @@ static PRTMEMHDR rtR0MemAllocExecVmArea(size_t cb)
for (iPage = 0; iPage < cPages; iPage++)
{
- papPages[iPage] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
+ papPages[iPage] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN);
if (!papPages[iPage])
break;
}
@@ -383,15 +383,15 @@ RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
cOrder = CalcPowerOf2Order(cPages);
#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
/* ZONE_DMA32: 0-4GB */
- paPages = alloc_pages(GFP_DMA32, cOrder);
+ paPages = alloc_pages(GFP_DMA32 | __GFP_NOWARN, cOrder);
if (!paPages)
#endif
#ifdef RT_ARCH_AMD64
/* ZONE_DMA; 0-16MB */
- paPages = alloc_pages(GFP_DMA, cOrder);
+ paPages = alloc_pages(GFP_DMA | __GFP_NOWARN, cOrder);
#else
/* ZONE_NORMAL: 0-896MB */
- paPages = alloc_pages(GFP_USER, cOrder);
+ paPages = alloc_pages(GFP_USER | __GFP_NOWARN, cOrder);
#endif
if (paPages)
{
diff --git a/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c
index 2a7fef9f..11b3a27e 100644
--- a/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007 Oracle Corporation
+ * Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
index 5cf9ad66..fda6e35f 100644
--- a/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
index e21af78c..2840dd4d 100644
--- a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
@@ -1,10 +1,10 @@
-/* $Revision: 81432 $ */
+/* $Revision: 91595 $ */
/** @file
* IPRT - Ring-0 Memory Objects, Linux.
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -320,9 +320,9 @@ static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE en
|| cb <= PAGE_SIZE * 2)
{
# ifdef VBOX_USE_INSERT_PAGE
- paPages = alloc_pages(fFlagsLnx | __GFP_COMP, rtR0MemObjLinuxOrder(cPages));
+ paPages = alloc_pages(fFlagsLnx | __GFP_COMP | __GFP_NOWARN, rtR0MemObjLinuxOrder(cPages));
# else
- paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages));
+ paPages = alloc_pages(fFlagsLnx | __GFP_NOWARN, rtR0MemObjLinuxOrder(cPages));
# endif
if (paPages)
{
@@ -341,7 +341,7 @@ static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE en
{
for (iPage = 0; iPage < cPages; iPage++)
{
- pMemLnx->apPages[iPage] = alloc_page(fFlagsLnx);
+ pMemLnx->apPages[iPage] = alloc_page(fFlagsLnx | __GFP_NOWARN);
if (RT_UNLIKELY(!pMemLnx->apPages[iPage]))
{
while (iPage-- > 0)
@@ -1170,7 +1170,7 @@ DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *
* Allocate a dummy page and create a page pointer array for vmap such that
* the dummy page is mapped all over the reserved area.
*/
- pDummyPage = alloc_page(GFP_HIGHUSER);
+ pDummyPage = alloc_page(GFP_HIGHUSER | __GFP_NOWARN);
if (!pDummyPage)
return VERR_NO_MEMORY;
papPages = RTMemAlloc(sizeof(*papPages) * cPages);
@@ -1407,7 +1407,7 @@ DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ p
/*
* Allocate a dummy page for use when mapping the memory.
*/
- pDummyPage = alloc_page(GFP_USER);
+ pDummyPage = alloc_page(GFP_USER | __GFP_NOWARN);
if (!pDummyPage)
return VERR_NO_MEMORY;
SetPageReserved(pDummyPage);
@@ -1527,6 +1527,25 @@ DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ p
}
}
+#ifdef CONFIG_NUMA_BALANCING
+ if (RT_SUCCESS(rc))
+ {
+ /** @todo Ugly hack! But right now we have no other means to disable
+ * automatic NUMA page balancing. */
+# ifdef RT_OS_X86
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+ pTask->mm->numa_next_reset = jiffies + 0x7fffffffUL;
+# endif
+ pTask->mm->numa_next_scan = jiffies + 0x7fffffffUL;
+# else
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+ pTask->mm->numa_next_reset = jiffies + 0x7fffffffffffffffUL;
+# endif
+ pTask->mm->numa_next_scan = jiffies + 0x7fffffffffffffffUL;
+# endif
+ }
+#endif
+
up_write(&pTask->mm->mmap_sem);
if (RT_SUCCESS(rc))
diff --git a/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
index 55431c99..211fc361 100644
--- a/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
index 32ab1234..88971ac5 100644
--- a/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c
index b2a6ab9c..687f3bbd 100644
--- a/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c
index e69aeace..ce2fe313 100644
--- a/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
index 2506adc8..9c4c131f 100644
--- a/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
index 74cc3900..702e1d00 100644
--- a/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
index 8297d6dd..25f07654 100644
--- a/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c
index 714bc35f..eb141e82 100644
--- a/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/spinlock-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -93,6 +93,7 @@ RTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char
pThis->idCpuOwner = NIL_RTCPUID;
pThis->idAssertCpu = NIL_RTCPUID;
#endif
+
spin_lock_init(&pThis->Spinlock);
*pSpinlock = pThis;
@@ -129,6 +130,9 @@ RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC,
("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0));
+#if defined(CONFIG_PROVE_LOCKING) && !defined(RT_STRICT)
+ lockdep_off();
+#endif
if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
{
unsigned long fIntSaved;
@@ -137,6 +141,9 @@ RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
}
else
spin_lock(&pThis->Spinlock);
+#if defined(CONFIG_PROVE_LOCKING) && !defined(RT_STRICT)
+ lockdep_on();
+#endif
RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis);
}
@@ -151,6 +158,9 @@ RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0));
RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pThis);
+#if defined(CONFIG_PROVE_LOCKING) && !defined(RT_STRICT)
+ lockdep_off();
+#endif
if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
{
unsigned long fIntSaved = pThis->fIntSaved;
@@ -159,6 +169,9 @@ RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
}
else
spin_unlock(&pThis->Spinlock);
+#if defined(CONFIG_PROVE_LOCKING) && !defined(RT_STRICT)
+ lockdep_on();
+#endif
RT_ASSERT_PREEMPT_CPUID();
}
diff --git a/src/VBox/Runtime/r0drv/linux/string.h b/src/VBox/Runtime/r0drv/linux/string.h
index f2f31941..2314d13c 100644
--- a/src/VBox/Runtime/r0drv/linux/string.h
+++ b/src/VBox/Runtime/r0drv/linux/string.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
index eebf6734..a1791eea 100644
--- a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
+++ b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -90,6 +90,9 @@
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+# include <linux/sched/rt.h>
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
# include <linux/jiffies.h>
#endif
@@ -121,6 +124,11 @@
#include <asm/uaccess.h>
#include <asm/div64.h>
+/* For thread-context hooks. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) && defined(CONFIG_PREEMPT_NOTIFIERS)
+# include <linux/preempt.h>
+#endif
+
/* for workqueue / task queues. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
# include <linux/workqueue.h>
@@ -142,6 +150,10 @@
# define DEFINE_WAIT(name) DECLARE_WAITQUEUE(name, current)
#endif
+#ifndef __GFP_NOWARN
+# define __GFP_NOWARN 0
+#endif
+
/*
* 2.4 / early 2.6 compatibility wrappers
*/
diff --git a/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
index ecd53717..d5b69d62 100644
--- a/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -87,6 +87,7 @@ RTDECL(bool) RTThreadYield(void)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20)
yield();
#else
+ /** @todo r=ramshankar: Can we use cond_resched() instead? */
set_current_state(TASK_RUNNING);
sys_sched_yield();
schedule();
@@ -159,6 +160,8 @@ RT_EXPORT_SYMBOL(RTThreadPreemptIsPendingTrusty);
RTDECL(bool) RTThreadPreemptIsPossible(void)
{
+ /** @todo r=ramshankar: What about CONFIG_PREEMPT_VOLUNTARY? That can preempt
+ * too but does so in voluntarily in explicit preemption points. */
#ifdef CONFIG_PREEMPT
return true; /* yes, kernel preemption is possible. */
#else
@@ -174,6 +177,7 @@ RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
AssertPtr(pState);
Assert(pState->u32Reserved == 0);
pState->u32Reserved = 42;
+ /* This ASSUMES that CONFIG_PREEMPT_COUNT is always defined with CONFIG_PREEMPT. */
preempt_disable();
RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
diff --git a/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
index a9561c42..01956565 100644
--- a/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c
new file mode 100644
index 00000000..c0b39371
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c
@@ -0,0 +1,330 @@
+/* $Id: threadctxhooks-r0drv-linux.c $ */
+/** @file
+ * IPRT - Thread-Context Hook, Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-linux-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/mem.h>
+#include <iprt/assert.h>
+#include <iprt/thread.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include "internal/thread.h"
+
+/*
+ * Linux kernel 2.6.23 introduced thread-context hooks but RedHat 2.6.18 kernels
+ * got it backported.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) && defined(CONFIG_PREEMPT_NOTIFIERS)
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * The internal thread-context object.
+ */
+typedef struct RTTHREADCTXINT
+{
+ /** Magic value (RTTHREADCTXINT_MAGIC). */
+ uint32_t volatile u32Magic;
+ /** The thread handle (owner) for which the context-hooks are registered. */
+ RTNATIVETHREAD hOwner;
+ /** The preemption notifier object. */
+ struct preempt_notifier hPreemptNotifier;
+ /** Whether this handle has any hooks registered or not. */
+ bool fRegistered;
+ /** Pointer to the registered thread-context hook. */
+ PFNRTTHREADCTXHOOK pfnThreadCtxHook;
+ /** User argument passed to the thread-context hook. */
+ void *pvUser;
+ /** The thread-context operations. */
+ struct preempt_ops hPreemptOps;
+ /** The reference count for this object. */
+ uint32_t volatile cRefs;
+} RTTHREADCTXINT, *PRTTHREADCTXINT;
+
+
+/**
+ * Hook function for the thread-preempting event.
+ *
+ * @param pPreemptNotifier Pointer to the preempt_notifier struct.
+ * @param pNext Pointer to the task that is preempting the
+ * current thread.
+ *
+ * @remarks Called with the rq (runqueue) lock held and with preemption and
+ * interrupts disabled!
+ */
+static void rtThreadCtxHooksLnxSchedOut(struct preempt_notifier *pPreemptNotifier, struct task_struct *pNext)
+{
+ PRTTHREADCTXINT pThis = RT_FROM_MEMBER(pPreemptNotifier, RTTHREADCTXINT, hPreemptNotifier);
+ AssertPtr(pThis);
+ AssertPtr(pThis->pfnThreadCtxHook);
+ Assert(pThis->fRegistered);
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ pThis->pfnThreadCtxHook(RTTHREADCTXEVENT_PREEMPTING, pThis->pvUser);
+}
+
+
+/**
+ * Hook function for the thread-resumed event.
+ *
+ * @param pPreemptNotifier Pointer to the preempt_notifier struct.
+ * @param iCpu The CPU this thread is scheduled on.
+ *
+ * @remarks Called without holding the rq (runqueue) lock and with preemption
+ * enabled!
+ */
+static void rtThreadCtxHooksLnxSchedIn(struct preempt_notifier *pPreemptNotifier, int iCpu)
+{
+ PRTTHREADCTXINT pThis = RT_FROM_MEMBER(pPreemptNotifier, RTTHREADCTXINT, hPreemptNotifier);
+ AssertPtr(pThis);
+ AssertPtr(pThis->pfnThreadCtxHook);
+ Assert(pThis->fRegistered);
+
+ pThis->pfnThreadCtxHook(RTTHREADCTXEVENT_RESUMED, pThis->pvUser);
+}
+
+
+/**
+ * Worker function for RTThreadCtxHooks(Deregister|Release)().
+ *
+ * @param pThis Pointer to the internal thread-context object.
+ */
+DECLINLINE(void) rtThreadCtxHooksDeregister(PRTTHREADCTXINT pThis)
+{
+ preempt_notifier_unregister(&pThis->hPreemptNotifier);
+ pThis->hPreemptOps.sched_out = NULL;
+ pThis->hPreemptOps.sched_in = NULL;
+ pThis->fRegistered = false;
+}
+
+
+RTDECL(int) RTThreadCtxHooksCreate(PRTTHREADCTX phThreadCtx)
+{
+ PRTTHREADCTXINT pThis;
+ Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ pThis = (PRTTHREADCTXINT)RTMemAllocZ(sizeof(*pThis));
+ if (RT_UNLIKELY(!pThis))
+ return VERR_NO_MEMORY;
+ pThis->u32Magic = RTTHREADCTXINT_MAGIC;
+ pThis->hOwner = RTThreadNativeSelf();
+ pThis->fRegistered = false;
+ preempt_notifier_init(&pThis->hPreemptNotifier, &pThis->hPreemptOps);
+ pThis->cRefs = 1;
+
+ *phThreadCtx = pThis;
+ return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksCreate);
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRetain(RTTHREADCTX hThreadCtx)
+{
+ /*
+ * Validate input.
+ */
+ uint32_t cRefs;
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ AssertPtr(pThis);
+ AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
+ UINT32_MAX);
+
+ cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ Assert(cRefs < UINT32_MAX / 2);
+ return cRefs;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRetain);
+
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRelease(RTTHREADCTX hThreadCtx)
+{
+ /*
+ * Validate input.
+ */
+ uint32_t cRefs;
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return 0;
+
+ AssertPtr(pThis);
+ AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
+ UINT32_MAX);
+ Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ cRefs = ASMAtomicDecU32(&pThis->cRefs);
+ if (!cRefs)
+ {
+ /*
+ * If there's still a registered thread-context hook, deregister it now before destroying the object.
+ */
+ if (pThis->fRegistered)
+ rtThreadCtxHooksDeregister(pThis);
+
+ /*
+ * Paranoia... but since these are ring-0 threads we can't be too careful.
+ */
+ Assert(!pThis->fRegistered);
+ Assert(!pThis->hPreemptOps.sched_out);
+ Assert(!pThis->hPreemptOps.sched_in);
+
+ ASMAtomicWriteU32(&pThis->u32Magic, ~RTTHREADCTXINT_MAGIC);
+ RTMemFree(pThis);
+ }
+ else
+ Assert(cRefs < UINT32_MAX / 2);
+
+ return cRefs;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRelease);
+
+
+RTDECL(int) RTThreadCtxHooksRegister(RTTHREADCTX hThreadCtx, PFNRTTHREADCTXHOOK pfnThreadCtxHook, void *pvUser)
+{
+ /*
+ * Validate input.
+ */
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return VERR_INVALID_HANDLE;
+ AssertPtr(pThis);
+ AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
+ VERR_INVALID_HANDLE);
+ Assert(pThis->hOwner == RTThreadNativeSelf());
+ Assert(!pThis->hPreemptOps.sched_out);
+ Assert(!pThis->hPreemptOps.sched_in);
+
+ /*
+ * Register the callback.
+ */
+ pThis->hPreemptOps.sched_out = rtThreadCtxHooksLnxSchedOut;
+ pThis->hPreemptOps.sched_in = rtThreadCtxHooksLnxSchedIn;
+ pThis->pvUser = pvUser;
+ pThis->pfnThreadCtxHook = pfnThreadCtxHook;
+ pThis->fRegistered = true;
+ preempt_notifier_register(&pThis->hPreemptNotifier);
+
+ return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRegister);
+
+
+RTDECL(int) RTThreadCtxHooksDeregister(RTTHREADCTX hThreadCtx)
+{
+ /*
+ * Validate input.
+ */
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return VERR_INVALID_HANDLE;
+ AssertPtr(pThis);
+ AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
+ VERR_INVALID_HANDLE);
+ Assert(pThis->hOwner == RTThreadNativeSelf());
+ Assert(pThis->fRegistered);
+
+ /*
+ * Deregister the callback.
+ */
+ rtThreadCtxHooksDeregister(pThis);
+ return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksDeregister);
+
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+ /*
+ * Validate input.
+ */
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return false;
+ AssertPtr(pThis);
+ AssertMsg(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis));
+
+ return pThis->fRegistered;
+}
+
+#else /* Not supported / Not needed */
+
+RTDECL(int) RTThreadCtxHooksCreate(PRTTHREADCTX phThreadCtx)
+{
+ NOREF(phThreadCtx);
+ return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksCreate);
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRetain(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return UINT32_MAX;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRetain);
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRelease(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return UINT32_MAX;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRelease);
+
+
+RTDECL(int) RTThreadCtxHooksRegister(RTTHREADCTX hThreadCtx, PFNRTTHREADCTXHOOK pfnThreadCtxHook, void *pvUser)
+{
+ NOREF(hThreadCtx);
+ NOREF(pfnThreadCtxHook);
+ NOREF(pvUser);
+ return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksRegister);
+
+
+RTDECL(int) RTThreadCtxHooksDeregister(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return VERR_NOT_SUPPORTED;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksDeregister);
+
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+ NOREF(hThreadCtx);
+ return false;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksAreRegistered);
+
+#endif /* Not supported / Not needed */
+
diff --git a/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c
index c0fb357f..cd2e70f1 100644
--- a/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
index 710a0489..b5c875d3 100644
--- a/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1557,7 +1557,7 @@ RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_
*/
if (cCpus > 1)
{
- int rc = RTSpinlockCreate(&pTimer->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "RTTimerLnx");
+ int rc = RTSpinlockCreate(&pTimer->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTTimerLnx");
if (RT_SUCCESS(rc))
rc = RTMpNotificationRegister(rtTimerLinuxMpEvent, pTimer);
else
diff --git a/src/VBox/Runtime/r0drv/memobj-r0drv.cpp b/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
index 622406e4..2d5c85c9 100644
--- a/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
+++ b/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
@@ -1,10 +1,10 @@
-/* $Revision: 77489 $ */
+/* $Revision: 89632 $ */
/** @file
* IPRT - Ring-0 Memory Objects, Common Code.
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -264,6 +264,12 @@ RT_EXPORT_SYMBOL(RTR0MemObjSize);
* @param MemObj The ring-0 memory object handle.
* @param iPage The page number within the object.
*/
+/* Work around gcc bug 55940 */
+#if defined(__GNUC__) && defined(RT_ARCH_X86)
+# if (__GNUC__ * 100 + __GNUC_MINOR__) == 407
+ __attribute__((__optimize__ ("no-shrink-wrap")))
+# endif
+#endif
RTR0DECL(RTHCPHYS) RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage)
{
/* Validate the object handle. */
diff --git a/src/VBox/Runtime/r0drv/mp-r0drv.h b/src/VBox/Runtime/r0drv/mp-r0drv.h
index 807ef642..0166cef3 100644
--- a/src/VBox/Runtime/r0drv/mp-r0drv.h
+++ b/src/VBox/Runtime/r0drv/mp-r0drv.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/mpnotification-r0drv.c b/src/VBox/Runtime/r0drv/mpnotification-r0drv.c
index b42be8c9..612ca01b 100644
--- a/src/VBox/Runtime/r0drv/mpnotification-r0drv.c
+++ b/src/VBox/Runtime/r0drv/mpnotification-r0drv.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -276,7 +276,7 @@ RT_EXPORT_SYMBOL(RTMpNotificationDeregister);
DECLHIDDEN(int) rtR0MpNotificationInit(void)
{
- int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "RTR0Mp");
+ int rc = RTSpinlockCreate((PRTSPINLOCK)&g_hRTMpNotifySpinLock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTR0Mp");
if (RT_SUCCESS(rc))
{
rc = rtR0MpNotificationNativeInit();
diff --git a/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp
index 95d6a112..0342dbd7 100644
--- a/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp
index 10b15115..e8720347 100644
--- a/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/alloc-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp
index 63728663..df6b5483 100644
--- a/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/assert-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
index 7f0d2153..a199e135 100644
--- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -35,12 +35,14 @@
#include <iprt/string.h>
#include "internal/initterm.h"
#include "internal-r0drv-nt.h"
+#include "symdb.h"
+#include "symdbdata.h"
/*******************************************************************************
* Global Variables *
*******************************************************************************/
-/** The Nt CPU set.
+/** The NT CPU set.
* KeQueryActiveProcssors() cannot be called at all IRQLs and therefore we'll
* have to cache it. Fortunately, Nt doesn't really support taking CPUs offline
* or online. It's first with W2K8 that support for CPU hotplugging was added.
@@ -61,6 +63,8 @@ PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
PFNRTSENDIPI g_pfnrtSendIpi;
/** KeIpiGenericCall - Windows Server 2003+ only */
PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
+/** RtlGetVersion, introduced in ??. */
+PFNRTRTLGETVERSION g_pfnrtRtlGetVersion;
/** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */
uint32_t g_offrtNtPbQuantumEnd;
@@ -70,6 +74,116 @@ uint32_t g_cbrtNtPbQuantumEnd;
uint32_t g_offrtNtPbDpcQueueDepth;
+/**
+ * Determines the NT kernel verison information.
+ *
+ * @param pOsVerInfo Where to return the version information.
+ *
+ * @remarks pOsVerInfo->fSmp is only definitive if @c true.
+ * @remarks pOsVerInfo->uCsdNo is set to MY_NIL_CSD if it cannot be determined.
+ */
+static void rtR0NtGetOsVersionInfo(PRTNTSDBOSVER pOsVerInfo)
+{
+ ULONG ulMajorVersion = 0;
+ ULONG ulMinorVersion = 0;
+ ULONG ulBuildNumber = 0;
+
+ pOsVerInfo->fChecked = PsGetVersion(&ulMajorVersion, &ulMinorVersion, &ulBuildNumber, NULL) == TRUE;
+ pOsVerInfo->uMajorVer = (uint8_t)ulMajorVersion;
+ pOsVerInfo->uMinorVer = (uint8_t)ulMinorVersion;
+ pOsVerInfo->uBuildNo = ulBuildNumber;
+#define MY_NIL_CSD 0x3f
+ pOsVerInfo->uCsdNo = MY_NIL_CSD;
+
+ if (g_pfnrtRtlGetVersion)
+ {
+ RTL_OSVERSIONINFOEXW VerInfo;
+ RT_ZERO(VerInfo);
+ VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
+
+ NTSTATUS rcNt = g_pfnrtRtlGetVersion(&VerInfo);
+ if (NT_SUCCESS(rcNt))
+ pOsVerInfo->uCsdNo = VerInfo.wServicePackMajor;
+ }
+
+ /* Note! We cannot quite say if something is MP or UNI. So, fSmp is
+ redefined to indicate that it must be MP. */
+ pOsVerInfo->fSmp = RTMpGetCount() > 1
+ || ulMajorVersion >= 6; /* Vista and later has no UNI kernel AFAIK. */
+}
+
+
+/**
+ * Tries a set against the current kernel.
+ *
+ * @retval @c true if it matched up, global variables are updated.
+ * @retval @c false otherwise (no globals updated).
+ * @param pSet The data set.
+ * @param pbPrcb Pointer to the processor control block.
+ * @param pszVendor Pointer to the processor vendor string.
+ * @param pOsVerInfo The OS version info.
+ */
+static bool rtR0NtTryMatchSymSet(PCRTNTSDBSET pSet, uint8_t *pbPrcb, const char *pszVendor, PCRTNTSDBOSVER pOsVerInfo)
+{
+ /*
+ * Don't bother trying stuff where the NT kernel version number differs, or
+ * if the build type or SMPness doesn't match up.
+ */
+ if ( pSet->OsVerInfo.uMajorVer != pOsVerInfo->uMajorVer
+ || pSet->OsVerInfo.uMinorVer != pOsVerInfo->uMinorVer
+ || pSet->OsVerInfo.fChecked != pOsVerInfo->fChecked
+ || (!pSet->OsVerInfo.fSmp && pOsVerInfo->fSmp /*must-be-smp*/) )
+ {
+ //DbgPrint("IPRT: #%d Version/type mismatch.\n", pSet - &g_artNtSdbSets[0]);
+ return false;
+ }
+
+ /*
+ * Do the CPU vendor test.
+ *
+ * Note! The MmIsAddressValid call is the real #PF security here as the
+ * __try/__except has limited/no ability to catch everything we need.
+ */
+ char *pszPrcbVendorString = (char *)&pbPrcb[pSet->KPRCB.offVendorString];
+ if (!MmIsAddressValid(&pszPrcbVendorString[4 * 3 - 1]))
+ {
+ //DbgPrint("IPRT: #%d invalid vendor string address.\n", pSet - &g_artNtSdbSets[0]);
+ return false;
+ }
+ __try
+ {
+ if (memcmp(pszPrcbVendorString, pszVendor, RT_MIN(4 * 3, pSet->KPRCB.cbVendorString)) != 0)
+ {
+ //DbgPrint("IPRT: #%d Vendor string mismatch.\n", pSet - &g_artNtSdbSets[0]);
+ return false;
+ }
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DbgPrint("IPRT: %#d Exception\n", pSet - &g_artNtSdbSets[0]);
+ return false;
+ }
+
+ /*
+ * Got a match, update the global variables and report succcess.
+ */
+ g_offrtNtPbQuantumEnd = pSet->KPRCB.offQuantumEnd;
+ g_cbrtNtPbQuantumEnd = pSet->KPRCB.cbQuantumEnd;
+ g_offrtNtPbDpcQueueDepth = pSet->KPRCB.offDpcQueueDepth;
+
+#if 0
+ DbgPrint("IPRT: Using data set #%u for %u.%usp%u build %u %s %s.\n",
+ pSet - &g_artNtSdbSets[0],
+ pSet->OsVerInfo.uMajorVer,
+ pSet->OsVerInfo.uMinorVer,
+ pSet->OsVerInfo.uCsdNo,
+ pSet->OsVerInfo.uBuildNo,
+ pSet->OsVerInfo.fSmp ? "smp" : "uni",
+ pSet->OsVerInfo.fChecked ? "checked" : "free");
+#endif
+ return true;
+}
+
DECLHIDDEN(int) rtR0InitNative(void)
{
@@ -91,6 +205,7 @@ DECLHIDDEN(int) rtR0InitNative(void)
g_pfnrtNtHalRequestIpi = NULL;
g_pfnrtNtHalSendSoftwareInterrupt = NULL;
g_pfnrtKeIpiGenericCall = NULL;
+ g_pfnrtRtlGetVersion = NULL;
#else
/*
* Initialize the function pointers.
@@ -110,35 +225,36 @@ DECLHIDDEN(int) rtR0InitNative(void)
RtlInitUnicodeString(&RoutineName, L"KeIpiGenericCall");
g_pfnrtKeIpiGenericCall = (PFNRTKEIPIGENERICCALL)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"RtlGetVersion");
+ g_pfnrtRtlGetVersion = (PFNRTRTLGETVERSION)MmGetSystemRoutineAddress(&RoutineName);
#endif
/*
- * Get some info that might come in handy below.
+ * HACK ALERT! (and déjà vu warning - remember win32k.sys?)
+ *
+ * Try find _KPRCB::QuantumEnd and _KPRCB::[DpcData.]DpcQueueDepth.
+ * For purpose of verification we use the VendorString member (12+1 chars).
+ *
+ * The offsets was initially derived by poking around with windbg
+ * (dt _KPRCB, !prcb ++, and such like). Systematic harvesting was then
+ * planned using dia2dump, grep and the symbol pack in a manner like this:
+ * dia2dump -type _KDPC_DATA -type _KPRCB EXE\ntkrnlmp.pdb | grep -wE "QuantumEnd|DpcData|DpcQueueDepth|VendorString"
+ *
+ * The final solution ended up using a custom harvester program called
+ * ntBldSymDb that recursively searches thru unpacked symbol packages for
+ * the desired structure offsets. The program assumes that the packages
+ * are unpacked into directories with the same name as the package, with
+ * exception of some of the w2k packages which requires a 'w2k' prefix to
+ * be distinguishable from another.
*/
- ULONG MajorVersion = 0;
- ULONG MinorVersion = 0;
- ULONG BuildNumber = 0;
- BOOLEAN fChecked = PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
- g_pfnrtSendIpi = rtMpSendIpiDummy;
-#ifndef IPRT_TARGET_NT4
- if ( g_pfnrtNtHalRequestIpi
- && MajorVersion == 6
- && MinorVersion == 0)
- {
- /* Vista or Windows Server 2008 */
- g_pfnrtSendIpi = rtMpSendIpiVista;
- }
- else
- if ( g_pfnrtNtHalSendSoftwareInterrupt
- && MajorVersion == 6
- && MinorVersion == 1)
- {
- /* Windows 7 or Windows Server 2008 R2 */
- g_pfnrtSendIpi = rtMpSendIpiWin7;
- }
- /* Windows XP should send always send an IPI -> VERIFY */
-#endif
+ RTNTSDBOSVER OsVerInfo;
+ rtR0NtGetOsVersionInfo(&OsVerInfo);
+
+ /*
+ * Gather consistent CPU vendor string and PRCB pointers.
+ */
KIRQL OldIrql;
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* make sure we stay on the same cpu */
@@ -150,115 +266,120 @@ DECLHIDDEN(int) rtR0InitNative(void)
ASMCpuId(0, &u.auRegs[3], &u.auRegs[0], &u.auRegs[2], &u.auRegs[1]);
u.szVendor[4*3] = '\0';
- /*
- * HACK ALERT (and déjà vu warning)!
- *
- * Try find _KPRCB::QuantumEnd and _KPRCB::[DpcData.]DpcQueueDepth.
- * For purpose of verification we use the VendorString member (12+1 chars).
- *
- * The offsets was initially derived by poking around with windbg
- * (dt _KPRCB, !prcb ++, and such like). Systematic harvesting is now done
- * by means of dia2dump, grep and the symbol packs. Typically:
- * dia2dump -type _KDPC_DATA -type _KPRCB EXE\ntkrnlmp.pdb | grep -wE "QuantumEnd|DpcData|DpcQueueDepth|VendorString"
- */
- /** @todo array w/ data + script for extracting a row. (save space + readability; table will be short.) */
- __try
+ uint8_t *pbPrcb;
+ __try /* Warning. This try/except statement may provide some false safety. */
{
#if defined(RT_ARCH_X86)
PKPCR pPcr = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
- uint8_t *pbPrcb = (uint8_t *)pPcr->Prcb;
-
- if ( BuildNumber == 2600 /* XP SP2 */
- && !memcmp(&pbPrcb[0x900], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x88c;
- g_cbrtNtPbQuantumEnd = 4;
- g_offrtNtPbDpcQueueDepth = 0x870;
- }
- /* WindowsVista.6002.090410-1830.x86fre.Symbols.exe
- WindowsVista.6002.090410-1830.x86chk.Symbols.exe
- WindowsVista.6002.090130-1715.x86fre.Symbols.exe
- WindowsVista.6002.090130-1715.x86chk.Symbols.exe */
- else if ( BuildNumber == 6002
- && !memcmp(&pbPrcb[0x1c2c], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x1a41;
- g_cbrtNtPbQuantumEnd = 1;
- g_offrtNtPbDpcQueueDepth = 0x19e0 + 0xc;
- }
- else if ( BuildNumber == 3790 /* Server 2003 SP2 */
- && !memcmp(&pbPrcb[0xb60], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x981;
- g_cbrtNtPbQuantumEnd = 1;
- g_offrtNtPbDpcQueueDepth = 0x920 + 0xc;
- }
-
- /** @todo more */
- //pbQuantumEnd = (uint8_t volatile *)pPcr->Prcb + 0x1a41;
-
+ pbPrcb = (uint8_t *)pPcr->Prcb;
#elif defined(RT_ARCH_AMD64)
PKPCR pPcr = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
- uint8_t *pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
-
- if ( BuildNumber == 3790 /* XP64 / W2K3-AMD64 SP1 */
- && !memcmp(&pbPrcb[0x22b4], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x1f75;
- g_cbrtNtPbQuantumEnd = 1;
- g_offrtNtPbDpcQueueDepth = 0x1f00 + 0x18;
- }
- else if ( BuildNumber == 6000 /* Vista/AMD64 */
- && !memcmp(&pbPrcb[0x38bc], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x3375;
- g_cbrtNtPbQuantumEnd = 1;
- g_offrtNtPbDpcQueueDepth = 0x3300 + 0x18;
- }
- /* WindowsVista.6002.090410-1830.amd64fre.Symbols
- WindowsVista.6002.090130-1715.amd64fre.Symbols
- WindowsVista.6002.090410-1830.amd64chk.Symbols */
- else if ( BuildNumber == 6002
- && !memcmp(&pbPrcb[0x399c], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x3475;
- g_cbrtNtPbQuantumEnd = 1;
- g_offrtNtPbDpcQueueDepth = 0x3400 + 0x18;
- }
- /* Windows7.7600.16539.amd64fre.win7_gdr.100226-1909 */
- else if ( BuildNumber == 7600
- && !memcmp(&pbPrcb[0x4bb8], &u.szVendor[0], 4*3))
- {
- g_offrtNtPbQuantumEnd = 0x21d9;
- g_cbrtNtPbQuantumEnd = 1;
- g_offrtNtPbDpcQueueDepth = 0x2180 + 0x18;
- }
-
+ pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
#else
# error "port me"
+ pbPrcb = NULL;
#endif
}
- __except(EXCEPTION_EXECUTE_HANDLER) /** @todo this handler doesn't seem to work... Because of Irql? */
+ __except(EXCEPTION_EXECUTE_HANDLER)
{
- g_offrtNtPbQuantumEnd = 0;
- g_cbrtNtPbQuantumEnd = 0;
- g_offrtNtPbDpcQueueDepth = 0;
+ pbPrcb = NULL;
}
- KeLowerIrql(OldIrql);
+ /*
+ * Search the database
+ */
+ if (pbPrcb)
+ {
+ /* Find the best matching kernel version based on build number. */
+ uint32_t iBest = UINT32_MAX;
+ int32_t iBestDelta = INT32_MAX;
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_artNtSdbSets); i++)
+ {
+ if (g_artNtSdbSets[i].OsVerInfo.fChecked != OsVerInfo.fChecked)
+ continue;
+ if (OsVerInfo.fSmp /*must-be-smp*/ && !g_artNtSdbSets[i].OsVerInfo.fSmp)
+ continue;
-#ifndef IN_GUEST /** @todo fix above for all Nt versions. */
+ int32_t iDelta = RT_ABS((int32_t)OsVerInfo.uBuildNo - (int32_t)g_artNtSdbSets[i].OsVerInfo.uBuildNo);
+ if ( iDelta == 0
+ && (g_artNtSdbSets[i].OsVerInfo.uCsdNo == OsVerInfo.uCsdNo || OsVerInfo.uCsdNo == MY_NIL_CSD))
+ {
+ /* prefect */
+ iBestDelta = iDelta;
+ iBest = i;
+ break;
+ }
+ if ( iDelta < iBestDelta
+ || iBest == UINT32_MAX
+ || ( iDelta == iBestDelta
+ && OsVerInfo.uCsdNo != MY_NIL_CSD
+ && RT_ABS(g_artNtSdbSets[i ].OsVerInfo.uCsdNo - (int32_t)OsVerInfo.uCsdNo)
+ < RT_ABS(g_artNtSdbSets[iBest].OsVerInfo.uCsdNo - (int32_t)OsVerInfo.uCsdNo)
+ )
+ )
+ {
+ iBestDelta = iDelta;
+ iBest = i;
+ }
+ }
+ if (iBest < RT_ELEMENTS(g_artNtSdbSets))
+ {
+ /* Try all sets: iBest -> End; iBest -> Start. */
+ bool fDone = false;
+ int32_t i = iBest;
+ while ( i < RT_ELEMENTS(g_artNtSdbSets)
+ && !(fDone = rtR0NtTryMatchSymSet(&g_artNtSdbSets[i], pbPrcb, u.szVendor, &OsVerInfo)))
+ i++;
+ if (!fDone)
+ {
+ i = (int32_t)iBest - 1;
+ while ( i >= 0
+ && !(fDone = rtR0NtTryMatchSymSet(&g_artNtSdbSets[i], pbPrcb, u.szVendor, &OsVerInfo)))
+ i--;
+ }
+ }
+ else
+ DbgPrint("IPRT: Failed to locate data set.\n");
+ }
+ else
+ DbgPrint("IPRT: Failed to get PCBR pointer.\n");
+
+ KeLowerIrql(OldIrql); /* Lowering the IRQL early in the hope that we may catch exceptions below. */
+
+#ifndef IN_GUEST
if (!g_offrtNtPbQuantumEnd && !g_offrtNtPbDpcQueueDepth)
DbgPrint("IPRT: Neither _KPRCB::QuantumEnd nor _KPRCB::DpcQueueDepth was not found! Kernel %u.%u %u %s\n",
- MajorVersion, MinorVersion, BuildNumber, fChecked ? "checked" : "free");
+ OsVerInfo.uMajorVer, OsVerInfo.uMinorVer, OsVerInfo.uBuildNo, OsVerInfo.fChecked ? "checked" : "free");
# ifdef DEBUG
else
- DbgPrint("IPRT: _KPRCB:{.QuantumEnd=%x/%d, .DpcQueueDepth=%x/%d} Kernel %ul.%ul %ul %s\n",
+ DbgPrint("IPRT: _KPRCB:{.QuantumEnd=%x/%d, .DpcQueueDepth=%x/%d} Kernel %u.%u %u %s\n",
g_offrtNtPbQuantumEnd, g_cbrtNtPbQuantumEnd, g_offrtNtPbDpcQueueDepth,
- MajorVersion, MinorVersion, BuildNumber, fChecked ? "checked" : "free");
+ OsVerInfo.uMajorVer, OsVerInfo.uMinorVer, OsVerInfo.uBuildNo, OsVerInfo.fChecked ? "checked" : "free");
# endif
#endif
+ /*
+ * Special IPI fun.
+ */
+ g_pfnrtSendIpi = rtMpSendIpiDummy;
+#ifndef IPRT_TARGET_NT4
+ if ( g_pfnrtNtHalRequestIpi
+ && OsVerInfo.uMajorVer == 6
+ && OsVerInfo.uMinorVer == 0)
+ {
+ /* Vista or Windows Server 2008 */
+ g_pfnrtSendIpi = rtMpSendIpiVista;
+ }
+ else if ( g_pfnrtNtHalSendSoftwareInterrupt
+ && OsVerInfo.uMajorVer == 6
+ && OsVerInfo.uMinorVer == 1)
+ {
+ /* Windows 7 or Windows Server 2008 R2 */
+ g_pfnrtSendIpi = rtMpSendIpiWin7;
+ }
+ /* Windows XP should send always send an IPI -> VERIFY */
+#endif
+
return VINF_SUCCESS;
}
diff --git a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
index e04230fa..a82c01f0 100644
--- a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
+++ b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -40,6 +40,7 @@ typedef VOID (__stdcall *PFNHALREQUESTIPI)(KAFFINITY TargetSet);
typedef VOID (__stdcall *PFNHALSENDSOFTWAREINTERRUPT)(ULONG ProcessorNumber, KIRQL Irql);
typedef int (__stdcall *PFNRTSENDIPI)(RTCPUID idCpu);
typedef ULONG_PTR (__stdcall *PFNRTKEIPIGENERICCALL)(PKIPI_BROADCAST_WORKER BroadcastFunction, ULONG_PTR Context);
+typedef ULONG (__stdcall *PFNRTRTLGETVERSION)(PRTL_OSVERSIONINFOEXW pVerInfo);
/*******************************************************************************
* Global Variables *
@@ -51,6 +52,7 @@ extern PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
extern PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
extern PFNRTSENDIPI g_pfnrtSendIpi;
extern PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
+extern PFNRTRTLGETVERSION g_pfnrtRtlGetVersion;
extern uint32_t g_offrtNtPbQuantumEnd;
extern uint32_t g_cbrtNtPbQuantumEnd;
extern uint32_t g_offrtNtPbDpcQueueDepth;
diff --git a/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
index a1cbd1b5..a1c0d865 100644
--- a/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp
index 05c359d5..982afb8f 100644
--- a/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/memuserkernel-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
index c606861f..643c34a1 100644
--- a/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp
index e334c353..56506d27 100644
--- a/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/mpnotification-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp b/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
new file mode 100644
index 00000000..0ffd6ca9
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/nt/ntBldSymDb.cpp
@@ -0,0 +1,1203 @@
+/* $Id: ntBldSymDb.cpp $ */
+/** @file
+ * IPRT - RTDirCreateUniqueNumbered, generic implementation.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <Windows.h>
+#include <Dbghelp.h>
+
+#include <iprt/alloca.h>
+#include <iprt/dir.h>
+#include <iprt/file.h>
+#include <iprt/getopt.h>
+#include <iprt/initterm.h>
+#include <iprt/list.h>
+#include <iprt/mem.h>
+#include <iprt/message.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/err.h>
+
+#include "r0drv/nt/symdb.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/** A structure member we're interested in. */
+typedef struct MYMEMBER
+{
+ /** The member name. */
+ const char * const pszName;
+ /** Reserved. */
+ uint32_t const fFlags;
+ /** The offset of the member. UINT32_MAX if not found. */
+ uint32_t off;
+ /** The size of the member. */
+ uint32_t cb;
+ /** Alternative names, optional.
+ * This is a string of zero terminated strings, ending with an zero length
+ * string (or double '\\0' if you like). */
+ const char * const pszzAltNames;
+} MYMEMBER;
+/** Pointer to a member we're interested. */
+typedef MYMEMBER *PMYMEMBER;
+
+/** Members we're interested in. */
+typedef struct MYSTRUCT
+{
+ /** The structure name. */
+ const char * const pszName;
+ /** Array of members we're interested in. */
+ MYMEMBER *paMembers;
+ /** The number of members we're interested in. */
+ uint32_t const cMembers;
+ /** Reserved. */
+ uint32_t const fFlags;
+} MYSTRUCT;
+
+/** Architecture. */
+typedef enum MYARCH
+{
+ MYARCH_X86,
+ MYARCH_AMD64,
+ MYARCH_DETECT
+} MYARCH;
+
+/** Set of structures for one kernel. */
+typedef struct MYSET
+{
+ /** The list entry. */
+ RTLISTNODE ListEntry;
+ /** The source PDB. */
+ char *pszPdb;
+ /** The OS version we've harvested structs for */
+ RTNTSDBOSVER OsVerInfo;
+ /** The architecture. */
+ MYARCH enmArch;
+ /** The structures and their member. */
+ MYSTRUCT aStructs[1];
+} MYSET;
+/** Pointer a set of structures for one kernel. */
+typedef MYSET *PMYSET;
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** Verbosity level (-v, --verbose). */
+static uint32_t g_iOptVerbose = 1;
+/** Set if we should force ahead despite errors. */
+static bool g_fOptForce = false;
+
+/** The members of the KPRCB structure that we're interested in. */
+static MYMEMBER g_aKprcbMembers[] =
+{
+ { "QuantumEnd", 0, UINT32_MAX, UINT32_MAX, NULL },
+ { "DpcQueueDepth", 0, UINT32_MAX, UINT32_MAX, "DpcData[0].DpcQueueDepth\0" },
+ { "VendorString", 0, UINT32_MAX, UINT32_MAX, NULL },
+};
+
+/** The structures we're interested in. */
+static MYSTRUCT g_aStructs[] =
+{
+ { "_KPRCB", &g_aKprcbMembers[0], RT_ELEMENTS(g_aKprcbMembers), 0 },
+};
+
+/** List of data we've found. This is sorted by version info. */
+static RTLISTANCHOR g_SetList;
+
+
+
+
+
+/**
+ * For debug/verbose output.
+ *
+ * @param pszFormat The format string.
+ * @param ... The arguments referenced in the format string.
+ */
+static void MyDbgPrintf(const char *pszFormat, ...)
+{
+ if (g_iOptVerbose > 1)
+ {
+ va_list va;
+ va_start(va, pszFormat);
+ RTPrintf("debug: ");
+ RTPrintfV(pszFormat, va);
+ va_end(va);
+ }
+}
+
+
+/**
+ * Returns the name we wish to use in the C code.
+ * @returns Structure name.
+ * @param pStruct The structure descriptor.
+ */
+static const char *figureCStructName(MYSTRUCT const *pStruct)
+{
+ const char *psz = pStruct->pszName;
+ while (*psz == '_')
+ psz++;
+ return psz;
+}
+
+
+/**
+ * Returns the name we wish to use in the C code.
+ * @returns Member name.
+ * @param pStruct The member descriptor.
+ */
+static const char *figureCMemberName(MYMEMBER const *pMember)
+{
+ return pMember->pszName;
+}
+
+
+/**
+ * Creates a MYSET with copies of all the data and inserts it into the
+ * g_SetList in a orderly fashion.
+ *
+ * @param pOut The output stream.
+ */
+static void generateHeader(PRTSTREAM pOut)
+{
+ RTStrmPrintf(pOut,
+ "/* $" "I" "d" ": $ */\n" /* avoid it being expanded */
+ "/** @file\n"
+ " * IPRT - NT kernel type helpers - Autogenerated, do NOT edit.\n"
+ " */\n"
+ "\n"
+ "/*\n"
+ " * Copyright (C) 2013 Oracle Corporation\n"
+ " *\n"
+ " * This file is part of VirtualBox Open Source Edition (OSE), as\n"
+ " * available from http://www.virtualbox.org. This file is free software;\n"
+ " * you can redistribute it and/or modify it under the terms of the GNU\n"
+ " * General Public License (GPL) as published by the Free Software\n"
+ " * Foundation, in version 2 as it comes in the \"COPYING\" file of the\n"
+ " * VirtualBox OSE distribution. VirtualBox OSE is distributed in the\n"
+ " * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.\n"
+ " *\n"
+ " * The contents of this file may alternatively be used under the terms\n"
+ " * of the Common Development and Distribution License Version 1.0\n"
+ " * (CDDL) only, as it comes in the \"COPYING.CDDL\" file of the\n"
+ " * VirtualBox OSE distribution, in which case the provisions of the\n"
+ " * CDDL are applicable instead of those of the GPL.\n"
+ " *\n"
+ " * You may elect to license modified versions of this file under the\n"
+ " * terms and conditions of either the GPL or the CDDL or both.\n"
+ " */\n"
+ "\n"
+ "\n"
+ "#ifndef ___r0drv_nt_symdbdata_h\n"
+ "#define ___r0drv_nt_symdbdata_h\n"
+ "\n"
+ "#include \"r0drv/nt/symdb.h\"\n"
+ "\n"
+ );
+
+ /*
+ * Generate types.
+ */
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aStructs); i++)
+ {
+ const char *pszStructName = figureCStructName(&g_aStructs[i]);
+
+ RTStrmPrintf(pOut,
+ "typedef struct RTNTSDBTYPE_%s\n"
+ "{\n",
+ pszStructName);
+ PMYMEMBER paMembers = g_aStructs[i].paMembers;
+ for (uint32_t j = 0; j < g_aStructs->cMembers; j++)
+ {
+ const char *pszMemName = figureCMemberName(&paMembers[j]);
+ RTStrmPrintf(pOut,
+ " uint32_t off%s;\n"
+ " uint32_t cb%s;\n",
+ pszMemName, pszMemName);
+ }
+
+ RTStrmPrintf(pOut,
+ "} RTNTSDBTYPE_%s;\n"
+ "\n",
+ pszStructName);
+ }
+
+ RTStrmPrintf(pOut,
+ "\n"
+ "typedef struct RTNTSDBSET\n"
+ "{\n"
+ " RTNTSDBOSVER%-20s OsVerInfo;\n", "");
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aStructs); i++)
+ {
+ const char *pszStructName = figureCStructName(&g_aStructs[i]);
+ RTStrmPrintf(pOut, " RTNTSDBTYPE_%-20s %s;\n", pszStructName, pszStructName);
+ }
+ RTStrmPrintf(pOut,
+ "} RTNTSDBSET;\n"
+ "typedef RTNTSDBSET const *PCRTNTSDBSET;\n"
+ "\n");
+
+ /*
+ * Output the data.
+ */
+ RTStrmPrintf(pOut,
+ "\n"
+ "#ifndef RTNTSDB_NO_DATA\n"
+ "const RTNTSDBSET g_artNtSdbSets[] = \n"
+ "{\n");
+ PMYSET pSet;
+ RTListForEach(&g_SetList, pSet, MYSET, ListEntry)
+ {
+ const char *pszArch = pSet->enmArch == MYARCH_AMD64 ? "AMD64" : "X86";
+ RTStrmPrintf(pOut,
+ "# ifdef RT_ARCH_%s\n"
+ " { /* Source: %s */\n"
+ " /*.OsVerInfo = */\n"
+ " {\n"
+ " /* .uMajorVer = */ %u,\n"
+ " /* .uMinorVer = */ %u,\n"
+ " /* .fChecked = */ %s,\n"
+ " /* .fSmp = */ %s,\n"
+ " /* .uCsdNo = */ %u,\n"
+ " /* .uBuildNo = */ %u,\n"
+ " },\n",
+ pszArch,
+ pSet->pszPdb,
+ pSet->OsVerInfo.uMajorVer,
+ pSet->OsVerInfo.uMinorVer,
+ pSet->OsVerInfo.fChecked ? "true" : "false",
+ pSet->OsVerInfo.fSmp ? "true" : "false",
+ pSet->OsVerInfo.uCsdNo,
+ pSet->OsVerInfo.uBuildNo);
+ for (uint32_t i = 0; i < RT_ELEMENTS(pSet->aStructs); i++)
+ {
+ const char *pszStructName = figureCStructName(&pSet->aStructs[i]);
+ RTStrmPrintf(pOut,
+ " /* .%s = */\n"
+ " {\n", pszStructName);
+ PMYMEMBER paMembers = pSet->aStructs[i].paMembers;
+ for (uint32_t j = 0; j < pSet->aStructs[i].cMembers; j++)
+ {
+ const char *pszMemName = figureCMemberName(&paMembers[j]);
+ RTStrmPrintf(pOut,
+ " /* .off%-25s = */ %#06x,\n"
+ " /* .cb%-26s = */ %#06x,\n",
+ pszMemName, paMembers[j].off,
+ pszMemName, paMembers[j].cb);
+ }
+ RTStrmPrintf(pOut,
+ " },\n");
+ }
+ RTStrmPrintf(pOut,
+ " },\n"
+ "# endif\n"
+ );
+ }
+
+ RTStrmPrintf(pOut,
+ "};\n"
+ "#endif /* !RTNTSDB_NO_DATA */\n"
+ "\n");
+
+ RTStrmPrintf(pOut, "\n#endif\n\n");
+}
+
+
+/**
+ * Creates a MYSET with copies of all the data and inserts it into the
+ * g_SetList in a orderly fashion.
+ *
+ * @returns Fully complained exit code.
+ * @param pOsVerInfo The OS version info.
+ */
+static RTEXITCODE saveStructures(PRTNTSDBOSVER pOsVerInfo, MYARCH enmArch, const char *pszPdb)
+{
+ /*
+ * Allocate one big chunk, figure it's size once.
+ */
+ static size_t s_cbNeeded = 0;
+ if (s_cbNeeded == 0)
+ {
+ s_cbNeeded = RT_OFFSETOF(MYSET, aStructs[RT_ELEMENTS(g_aStructs)]);
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aStructs); i++)
+ s_cbNeeded += sizeof(MYMEMBER) * g_aStructs[i].cMembers;
+ }
+
+ size_t cbPdb = strlen(pszPdb) + 1;
+ PMYSET pSet = (PMYSET)RTMemAlloc(s_cbNeeded + cbPdb);
+ if (!pSet)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Out of memory!\n");
+
+ /*
+ * Copy over the data.
+ */
+ pSet->enmArch = enmArch;
+ memcpy(&pSet->OsVerInfo, pOsVerInfo, sizeof(pSet->OsVerInfo));
+ memcpy(&pSet->aStructs[0], g_aStructs, sizeof(g_aStructs));
+
+ PMYMEMBER pDst = (PMYMEMBER)&pSet->aStructs[RT_ELEMENTS(g_aStructs)];
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aStructs); i++)
+ {
+ pSet->aStructs[i].paMembers = pDst;
+ memcpy(pDst, g_aStructs[i].paMembers, g_aStructs[i].cMembers * sizeof(*pDst));
+ pDst += g_aStructs[i].cMembers;
+ }
+
+ pSet->pszPdb = (char *)pDst;
+ memcpy(pDst, pszPdb, cbPdb);
+
+ /*
+ * Link it.
+ */
+ PMYSET pInsertBefore;
+ RTListForEach(&g_SetList, pInsertBefore, MYSET, ListEntry)
+ {
+ int iDiff = rtNtOsVerInfoCompare(&pInsertBefore->OsVerInfo, &pSet->OsVerInfo);
+ if (iDiff >= 0)
+ {
+ if (iDiff > 0 || pInsertBefore->enmArch > pSet->enmArch)
+ {
+ RTListNodeInsertBefore(&pInsertBefore->ListEntry, &pSet->ListEntry);
+ return RTEXITCODE_SUCCESS;
+ }
+ }
+ }
+
+ RTListAppend(&g_SetList, &pSet->ListEntry);
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Checks that we found everything.
+ *
+ * @returns Fully complained exit code.
+ */
+static RTEXITCODE checkThatWeFoundEverything(void)
+{
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aStructs); i++)
+ {
+ PMYMEMBER paMembers = g_aStructs[i].paMembers;
+ uint32_t j = g_aStructs[i].cMembers;
+ while (j-- > 0)
+ {
+ if (paMembers[j].off == UINT32_MAX)
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, " Missing %s::%s\n", g_aStructs[i].pszName, paMembers[j].pszName);
+ }
+ }
+ return rcExit;
+}
+
+
+/**
+ * Matches the member against what we're looking for.
+ *
+ * @returns Number of hits.
+ * @param cWantedMembers The number members in paWantedMembers.
+ * @param paWantedMembers The members we're looking for.
+ * @param pszPrefix The member name prefix.
+ * @param pszMember The member name.
+ * @param offMember The member offset.
+ * @param cbMember The member size.
+ */
+static uint32_t matchUpStructMembers(unsigned cWantedMembers, PMYMEMBER paWantedMembers,
+ const char *pszPrefix, const char *pszMember,
+ uint32_t offMember, uint32_t cbMember)
+{
+ size_t cchPrefix = strlen(pszPrefix);
+ uint32_t cHits = 0;
+ uint32_t iMember = cWantedMembers;
+ while (iMember-- > 0)
+ {
+ if ( !strncmp(pszPrefix, paWantedMembers[iMember].pszName, cchPrefix)
+ && !strcmp(pszMember, paWantedMembers[iMember].pszName + cchPrefix))
+ {
+ paWantedMembers[iMember].off = offMember;
+ paWantedMembers[iMember].cb = cbMember;
+ cHits++;
+ }
+ else if (paWantedMembers[iMember].pszzAltNames)
+ {
+ char const *pszCur = paWantedMembers[iMember].pszzAltNames;
+ while (*pszCur)
+ {
+ size_t cchCur = strlen(pszCur);
+ if ( !strncmp(pszPrefix, pszCur, cchPrefix)
+ && !strcmp(pszMember, pszCur + cchPrefix))
+ {
+ paWantedMembers[iMember].off = offMember;
+ paWantedMembers[iMember].cb = cbMember;
+ cHits++;
+ break;
+ }
+ pszCur += cchCur + 1;
+ }
+ }
+ }
+ return cHits;
+}
+
+
+/**
+ * Resets the writable structure members prior to processing a PDB.
+ *
+ * While processing the PDB, will fill in the sizes and offsets of what we find.
+ * Afterwards we'll use look for reset values to see that every structure and
+ * member was located successfully.
+ */
+static void resetMyStructs(void)
+{
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aStructs); i++)
+ {
+ PMYMEMBER paMembers = g_aStructs[i].paMembers;
+ uint32_t j = g_aStructs[i].cMembers;
+ while (j-- > 0)
+ {
+ paMembers[j].off = UINT32_MAX;
+ paMembers[j].cb = UINT32_MAX;
+ }
+ }
+}
+
+
+/**
+ * Find members in the specified structure type (@a idxType).
+ *
+ * @returns Fully bitched exit code.
+ * @param hFake Fake process handle.
+ * @param uModAddr The module address.
+ * @param idxType The type index of the structure which members we're
+ * going to process.
+ * @param cWantedMembers The number of wanted members.
+ * @param paWantedMembers The wanted members. This will be modified.
+ * @param offDisp Displacement when calculating member offsets.
+ * @param pszStructNm The top level structure name.
+ * @param pszPrefix The member name prefix.
+ * @param pszLogTag The log tag.
+ */
+static RTEXITCODE findMembers(HANDLE hFake, uint64_t uModAddr, uint32_t idxType,
+ uint32_t cWantedMembers, PMYMEMBER paWantedMembers,
+ uint32_t offDisp, const char *pszStructNm, const char *pszPrefix, const char *pszLogTag)
+{
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+
+ DWORD cChildren = 0;
+ if (!SymGetTypeInfo(hFake, uModAddr, idxType, TI_GET_CHILDRENCOUNT, &cChildren))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: TI_GET_CHILDRENCOUNT failed on _KPRCB: %u\n", pszLogTag, GetLastError());
+
+ MyDbgPrintf(" %s: cChildren=%u (%#x)\n", pszStructNm, cChildren);
+ TI_FINDCHILDREN_PARAMS *pChildren;
+ pChildren = (TI_FINDCHILDREN_PARAMS *)alloca(RT_OFFSETOF(TI_FINDCHILDREN_PARAMS, ChildId[cChildren]));
+ pChildren->Start = 0;
+ pChildren->Count = cChildren;
+ if (!SymGetTypeInfo(hFake, uModAddr, idxType, TI_FINDCHILDREN, pChildren))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: TI_FINDCHILDREN failed on _KPRCB: %u\n", pszLogTag, GetLastError());
+
+ for (uint32_t i = 0; i < cChildren; i++)
+ {
+ //MyDbgPrintf(" %s: child#%u: TypeIndex=%u\n", pszStructNm, i, pChildren->ChildId[i]);
+ IMAGEHLP_SYMBOL_TYPE_INFO enmErr;
+ PWCHAR pwszMember = NULL;
+ uint32_t idxRefType = 0;
+ uint32_t offMember = 0;
+ uint64_t cbMember = 0;
+ uint32_t cMemberChildren = 0;
+ if ( SymGetTypeInfo(hFake, uModAddr, pChildren->ChildId[i], enmErr = TI_GET_SYMNAME, &pwszMember)
+ && SymGetTypeInfo(hFake, uModAddr, pChildren->ChildId[i], enmErr = TI_GET_OFFSET, &offMember)
+ && SymGetTypeInfo(hFake, uModAddr, pChildren->ChildId[i], enmErr = TI_GET_TYPE, &idxRefType)
+ && SymGetTypeInfo(hFake, uModAddr, idxRefType, enmErr = TI_GET_LENGTH, &cbMember)
+ && SymGetTypeInfo(hFake, uModAddr, idxRefType, enmErr = TI_GET_CHILDRENCOUNT, &cMemberChildren)
+ )
+ {
+ offMember += offDisp;
+
+ char *pszMember;
+ int rc = RTUtf16ToUtf8(pwszMember, &pszMember);
+ if (RT_SUCCESS(rc))
+ {
+ matchUpStructMembers(cWantedMembers, paWantedMembers, pszPrefix, pszMember, offMember, cbMember);
+
+ /*
+ * Gather more info and do some debug printing. We'll use some
+ * of this info below when recursing into sub-structures
+ * and arrays.
+ */
+ uint32_t fNested = 0; SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_NESTED, &fNested);
+ uint32_t uDataKind = 0; SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_DATAKIND, &uDataKind);
+ uint32_t uBaseType = 0; SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_BASETYPE, &uBaseType);
+ uint32_t uMembTag = 0; SymGetTypeInfo(hFake, uModAddr, pChildren->ChildId[i], TI_GET_SYMTAG, &uMembTag);
+ uint32_t uBaseTag = 0; SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_SYMTAG, &uBaseTag);
+ uint32_t cElements = 0; SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_COUNT, &cElements);
+ uint32_t idxArrayType = 0; SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_ARRAYINDEXTYPEID, &idxArrayType);
+ MyDbgPrintf(" %#06x LB %#06llx %c%c %2d %2d %2d %2d %2d %4d %s::%s%s\n",
+ offMember, cbMember,
+ cMemberChildren > 0 ? 'c' : '-',
+ fNested != 0 ? 'n' : '-',
+ uDataKind,
+ uBaseType,
+ uMembTag,
+ uBaseTag,
+ cElements,
+ idxArrayType,
+ pszStructNm,
+ pszPrefix,
+ pszMember);
+
+ /*
+ * Recurse into children.
+ */
+ if (cMemberChildren > 0)
+ {
+ size_t cbNeeded = strlen(pszMember) + strlen(pszPrefix) + sizeof(".");
+ char *pszSubPrefix = (char *)RTMemTmpAlloc(cbNeeded);
+ if (pszSubPrefix)
+ {
+ strcat(strcat(strcpy(pszSubPrefix, pszPrefix), pszMember), ".");
+ RTEXITCODE rcExit2 = findMembers(hFake, uModAddr, idxRefType, cWantedMembers,
+ paWantedMembers, offMember,
+ pszStructNm,
+ pszSubPrefix,
+ pszLogTag);
+ if (rcExit2 != RTEXITCODE_SUCCESS)
+ rcExit = rcExit2;
+ RTMemTmpFree(pszSubPrefix);
+ }
+ else
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "out of memory\n");
+ }
+ /*
+ * Recurse into arrays too.
+ */
+ else if (cElements > 0 && idxArrayType > 0)
+ {
+ BOOL fRc;
+ uint32_t idxElementRefType = 0;
+ fRc = SymGetTypeInfo(hFake, uModAddr, idxRefType, TI_GET_TYPE, &idxElementRefType); Assert(fRc);
+ uint64_t cbElement = cbMember / cElements;
+ fRc = SymGetTypeInfo(hFake, uModAddr, idxElementRefType, TI_GET_LENGTH, &cbElement); Assert(fRc);
+ MyDbgPrintf("idxArrayType=%u idxElementRefType=%u cbElement=%u\n", idxArrayType, idxElementRefType, cbElement);
+
+ size_t cbNeeded = strlen(pszMember) + strlen(pszPrefix) + sizeof("[xxxxxxxxxxxxxxxx].");
+ char *pszSubPrefix = (char *)RTMemTmpAlloc(cbNeeded);
+ if (pszSubPrefix)
+ {
+ for (uint32_t iElement = 0; iElement < cElements; iElement++)
+ {
+ RTStrPrintf(pszSubPrefix, cbNeeded, "%s%s[%u].", pszPrefix, pszMember, iElement);
+ RTEXITCODE rcExit2 = findMembers(hFake, uModAddr, idxElementRefType, cWantedMembers,
+ paWantedMembers,
+ offMember + iElement * cbElement,
+ pszStructNm,
+ pszSubPrefix,
+ pszLogTag);
+ if (rcExit2 != RTEXITCODE_SUCCESS)
+ rcExit = rcExit2;
+ }
+ RTMemTmpFree(pszSubPrefix);
+ }
+ else
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "out of memory\n");
+ }
+
+ RTStrFree(pszMember);
+ }
+ else
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: RTUtf16ToUtf8 failed on %s child#%u: %Rrc\n",
+ pszLogTag, pszStructNm, i, rc);
+ }
+ /* TI_GET_OFFSET fails on bitfields, so just ignore+skip those. */
+ else if (enmErr != TI_GET_OFFSET || GetLastError() != ERROR_INVALID_FUNCTION)
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: SymGetTypeInfo(,,,%d,) failed on %s child#%u: %u\n",
+ pszLogTag, enmErr, pszStructNm, i, GetLastError());
+ LocalFree(pwszMember);
+ } /* For each child. */
+
+ return rcExit;
+}
+
+
+/**
+ * Lookup up structures and members in the given module.
+ *
+ * @returns Fully bitched exit code.
+ * @param hFake Fake process handle.
+ * @param uModAddr The module address.
+ * @param pszLogTag The log tag.
+ * @param pszPdb The full PDB path.
+ * @param pOsVerInfo The OS version info for altering the error handling
+ * for older OSes.
+ */
+static RTEXITCODE findStructures(HANDLE hFake, uint64_t uModAddr, const char *pszLogTag, const char *pszPdb,
+ PCRTNTSDBOSVER pOsVerInfo)
+{
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ PSYMBOL_INFO pSymInfo = (PSYMBOL_INFO)alloca(sizeof(*pSymInfo));
+ for (uint32_t iStruct = 0; iStruct < RT_ELEMENTS(g_aStructs); iStruct++)
+ {
+ pSymInfo->SizeOfStruct = sizeof(*pSymInfo);
+ pSymInfo->MaxNameLen = 0;
+ if (!SymGetTypeFromName(hFake, uModAddr, g_aStructs[iStruct].pszName, pSymInfo))
+ {
+ if (!(pOsVerInfo->uMajorVer == 5 && pOsVerInfo->uMinorVer == 0) /* w2k */)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Failed to find _KPRCB: %u\n", pszPdb, GetLastError());
+ RTMsgInfo("%s: Skipping - failed to find _KPRCB: %u\n", pszPdb, GetLastError());
+ return RTEXITCODE_SKIPPED;
+ }
+
+ MyDbgPrintf(" %s: TypeIndex=%u\n", g_aStructs[iStruct].pszName, pSymInfo->TypeIndex);
+ MyDbgPrintf(" %s: Size=%u (%#x)\n", g_aStructs[iStruct].pszName, pSymInfo->Size, pSymInfo->Size);
+
+ rcExit = findMembers(hFake, uModAddr, pSymInfo->TypeIndex,
+ g_aStructs[iStruct].cMembers, g_aStructs[iStruct].paMembers, 0 /* offDisp */,
+ g_aStructs[iStruct].pszName, "", pszLogTag);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ } /* for each struct we want */
+ return rcExit;
+}
+
+
+static bool strIEndsWith(const char *pszString, const char *pszSuffix)
+{
+ size_t cchString = strlen(pszString);
+ size_t cchSuffix = strlen(pszSuffix);
+ if (cchString < cchSuffix)
+ return false;
+ return RTStrICmp(pszString + cchString - cchSuffix, pszSuffix) == 0;
+}
+
+
+/**
+ * Use various hysterics to figure out the OS version details from the PDB path.
+ *
+ * This ASSUMES quite a bunch of things:
+ * -# Working on unpacked symbol packages. This does not work for
+ * windbg symbol stores/caches.
+ * -# The symbol package has been unpacked into a directory with the same
+ * name as the symbol package (sans suffixes).
+ *
+ * @returns Fully complained exit code.
+ * @param pszPdb The path to the PDB.
+ * @param pVerInfo Where to return the version info.
+ * @param penmArch Where to return the architecture.
+ */
+static RTEXITCODE FigurePdbVersionInfo(const char *pszPdb, PRTNTSDBOSVER pVerInfo, MYARCH *penmArch)
+{
+ /*
+ * Split the path.
+ */
+ union
+ {
+ RTPATHSPLIT Split;
+ uint8_t abPad[RTPATH_MAX + 1024];
+ } u;
+ int rc = RTPathSplit(pszPdb, &u.Split, sizeof(u), 0);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathSplit failed on '%s': %Rrc", pszPdb, rc);
+ if (!(u.Split.fProps & RTPATH_PROP_FILENAME))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPATH_PROP_FILENAME not set for: '%s'", pszPdb);
+ const char *pszFilename = u.Split.apszComps[u.Split.cComps - 1];
+
+ /*
+ * SMP or UNI kernel?
+ */
+ if ( !RTStrICmp(pszFilename, "ntkrnlmp.pdb")
+ || !RTStrICmp(pszFilename, "ntkrpamp.pdb")
+ )
+ pVerInfo->fSmp = true;
+ else if ( !RTStrICmp(pszFilename, "ntoskrnl.pdb")
+ || !RTStrICmp(pszFilename, "ntkrnlpa.pdb")
+ )
+ pVerInfo->fSmp = false;
+ else
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Doesn't recognize the filename '%s'...", pszFilename);
+
+ /*
+ * Look for symbol pack names in the path. This is stuff like:
+ * - WindowsVista.6002.090410-1830.x86fre
+ * - WindowsVista.6002.090410-1830.amd64chk
+ * - Windows_Win7.7600.16385.090713-1255.X64CHK
+ * - Windows_Win7SP1.7601.17514.101119-1850.AMD64FRE
+ * - Windows_Win8.9200.16384.120725-1247.X86CHK
+ * - en_windows_8_1_symbols_debug_checked_x64_2712568
+ */
+ bool fFound = false;
+ uint32_t i = u.Split.cComps - 1;
+ while (i-- > 0)
+ {
+ static struct
+ {
+ const char *pszPrefix;
+ size_t cchPrefix;
+ uint8_t uMajorVer;
+ uint8_t uMinorVer;
+ uint8_t uCsdNo;
+ uint32_t uBuildNo; /**< UINT32_MAX means the number immediately after the prefix. */
+ } const s_aSymPacks[] =
+ {
+ { RT_STR_TUPLE("w2kSP1SYM"), 5, 0, 1, 2195 },
+ { RT_STR_TUPLE("w2ksp2srp1"), 5, 0, 2, 2195 },
+ { RT_STR_TUPLE("w2ksp2sym"), 5, 0, 2, 2195 },
+ { RT_STR_TUPLE("w2ksp3sym"), 5, 0, 3, 2195 },
+ { RT_STR_TUPLE("w2ksp4sym"), 5, 0, 4, 2195 },
+ { RT_STR_TUPLE("Windows2000-KB891861"), 5, 0, 4, 2195 },
+ { RT_STR_TUPLE("windowsxp"), 5, 1, 0, 2600 },
+ { RT_STR_TUPLE("xpsp1sym"), 5, 1, 1, 2600 },
+ { RT_STR_TUPLE("WindowsXP-KB835935-SP2-"), 5, 1, 2, 2600 },
+ { RT_STR_TUPLE("WindowsXP-KB936929-SP3-"), 5, 1, 3, 2600 },
+ { RT_STR_TUPLE("Windows2003."), 5, 2, 0, 3790 },
+ { RT_STR_TUPLE("Windows2003_sp1."), 5, 2, 1, 3790 },
+ { RT_STR_TUPLE("WindowsServer2003-KB933548-v1"), 5, 2, 1, 3790 },
+ { RT_STR_TUPLE("WindowsVista.6000."), 6, 0, 0, 6000 },
+ { RT_STR_TUPLE("Windows_Longhorn.6001."), 6, 0, 1, 6001 }, /* incl w2k8 */
+ { RT_STR_TUPLE("WindowsVista.6002."), 6, 0, 2, 6002 }, /* incl w2k8 */
+ { RT_STR_TUPLE("Windows_Winmain.7000"), 6, 1, 0, 7000 }, /* Beta */
+ { RT_STR_TUPLE("Windows_Winmain.7100"), 6, 1, 0, 7100 }, /* RC */
+ { RT_STR_TUPLE("Windows_Win7.7600"), 6, 1, 0, 7600 }, /* RC */
+ { RT_STR_TUPLE("Windows_Win7SP1.7601"), 6, 1, 1, 7601 }, /* RC */
+ { RT_STR_TUPLE("Windows_Winmain.8102"), 6, 2, 0, 8102 }, /* preview */
+ { RT_STR_TUPLE("Windows_Winmain.8250"), 6, 2, 0, 8250 }, /* beta */
+ { RT_STR_TUPLE("Windows_Winmain.8400"), 6, 2, 0, 8400 }, /* RC */
+ { RT_STR_TUPLE("Windows_Win8.9200"), 6, 2, 0, 9200 }, /* RTM */
+ { RT_STR_TUPLE("en_windows_8_1"), 6, 3, 0, 9600 }, /* RTM */
+ };
+
+ const char *pszComp = u.Split.apszComps[i];
+ uint32_t iSymPack = RT_ELEMENTS(s_aSymPacks);
+ while (iSymPack-- > 0)
+ if (!RTStrNICmp(pszComp, s_aSymPacks[iSymPack].pszPrefix, s_aSymPacks[iSymPack].cchPrefix))
+ break;
+ if (iSymPack >= RT_ELEMENTS(s_aSymPacks))
+ continue;
+
+ pVerInfo->uMajorVer = s_aSymPacks[iSymPack].uMajorVer;
+ pVerInfo->uMinorVer = s_aSymPacks[iSymPack].uMinorVer;
+ pVerInfo->uCsdNo = s_aSymPacks[iSymPack].uCsdNo;
+ pVerInfo->fChecked = false;
+ pVerInfo->uBuildNo = s_aSymPacks[iSymPack].uBuildNo;
+
+ /* Parse build number if necessary. */
+ if (s_aSymPacks[iSymPack].uBuildNo == UINT32_MAX)
+ {
+ char *pszNext;
+ rc = RTStrToUInt32Ex(pszComp + s_aSymPacks[iSymPack].cchPrefix, &pszNext, 10, &pVerInfo->uBuildNo);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to decode build number in '%s': %Rrc", pszComp, rc);
+ if (*pszNext != '.' && *pszNext != '_' && *pszNext != '-')
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to decode build number in '%s': '%c'", pszComp, *pszNext);
+ }
+
+ /* Look for build arch and checked/free. */
+ if ( RTStrIStr(pszComp, ".x86.chk.")
+ || RTStrIStr(pszComp, ".x86chk.")
+ || RTStrIStr(pszComp, "_x86_chk_")
+ || RTStrIStr(pszComp, "_x86chk_")
+ || RTStrIStr(pszComp, "-x86-DEBUG")
+ || (RTStrIStr(pszComp, "-x86-") && RTStrIStr(pszComp, "-DEBUG"))
+ || RTStrIStr(pszComp, "_debug_checked_x86")
+ )
+ {
+ pVerInfo->fChecked = true;
+ *penmArch = MYARCH_X86;
+ }
+ else if ( RTStrIStr(pszComp, ".amd64.chk.")
+ || RTStrIStr(pszComp, ".amd64chk.")
+ || RTStrIStr(pszComp, ".x64.chk.")
+ || RTStrIStr(pszComp, ".x64chk.")
+ || RTStrIStr(pszComp, "_debug_checked_x64")
+ )
+ {
+ pVerInfo->fChecked = true;
+ *penmArch = MYARCH_AMD64;
+ }
+ else if ( RTStrIStr(pszComp, ".amd64.fre.")
+ || RTStrIStr(pszComp, ".amd64fre.")
+ || RTStrIStr(pszComp, ".x64.fre.")
+ || RTStrIStr(pszComp, ".x64fre.")
+ )
+ {
+ pVerInfo->fChecked = false;
+ *penmArch = MYARCH_AMD64;
+ }
+ else if ( RTStrIStr(pszComp, "DEBUG")
+ || RTStrIStr(pszComp, "_chk")
+ )
+ {
+ pVerInfo->fChecked = true;
+ *penmArch = MYARCH_X86;
+ }
+ else if (RTStrIStr(pszComp, "_x64"))
+ {
+ pVerInfo->fChecked = false;
+ *penmArch = MYARCH_AMD64;
+ }
+ else
+ {
+ pVerInfo->fChecked = false;
+ *penmArch = MYARCH_X86;
+ }
+ return RTEXITCODE_SUCCESS;
+ }
+
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Giving up on '%s'...\n", pszPdb);
+}
+
+
+/**
+ * Process one PDB.
+ *
+ * @returns Fully bitched exit code.
+ * @param pszPdb The path to the PDB.
+ */
+static RTEXITCODE processPdb(const char *pszPdb)
+{
+ /*
+ * We need the size later on, so get that now and present proper IPRT error
+ * info if the file is missing or inaccessible.
+ */
+ RTFSOBJINFO ObjInfo;
+ int rc = RTPathQueryInfoEx(pszPdb, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathQueryInfo fail on '%s': %Rrc\n", pszPdb, rc);
+
+ /*
+ * Figure the windows version details for the given PDB.
+ */
+ MYARCH enmArch;
+ RTNTSDBOSVER OsVerInfo;
+ RTEXITCODE rcExit = FigurePdbVersionInfo(pszPdb, &OsVerInfo, &enmArch);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to figure the OS version info for '%s'.\n'", pszPdb);
+
+ /*
+ * Create a fake handle and open the PDB.
+ */
+ static uintptr_t s_iHandle = 0;
+ HANDLE hFake = (HANDLE)++s_iHandle;
+ if (!SymInitialize(hFake, NULL, FALSE))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymInitialied failed: %u\n", GetLastError());
+
+ uint64_t uModAddr = UINT64_C(0x1000000);
+ uModAddr = SymLoadModuleEx(hFake, NULL /*hFile*/, pszPdb, NULL /*pszModuleName*/,
+ uModAddr, ObjInfo.cbObject, NULL /*pData*/, 0 /*fFlags*/);
+ if (uModAddr != 0)
+ {
+ MyDbgPrintf("*** uModAddr=%#llx \"%s\" ***\n", uModAddr, pszPdb);
+
+ char szLogTag[32];
+ RTStrCopy(szLogTag, sizeof(szLogTag), RTPathFilename(pszPdb));
+
+ /*
+ * Find the structures.
+ */
+ rcExit = findStructures(hFake, uModAddr, szLogTag, pszPdb, &OsVerInfo);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ rcExit = checkThatWeFoundEverything();
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ /*
+ * Save the details for later when we produce the header.
+ */
+ rcExit = saveStructures(&OsVerInfo, enmArch, pszPdb);
+ }
+ }
+ else
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymLoadModuleEx failed: %u\n", GetLastError());
+
+ if (!SymCleanup(hFake))
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymCleanup failed: %u\n", GetLastError());
+
+ if (rcExit == RTEXITCODE_SKIPPED)
+ rcExit = RTEXITCODE_SUCCESS;
+ return rcExit;
+}
+
+
+/** The size of the directory entry buffer we're using. */
+#define MY_DIRENTRY_BUF_SIZE (sizeof(RTDIRENTRYEX) + RTPATH_MAX)
+
+/**
+ * Checks if the name is of interest to us.
+ *
+ * @returns true/false.
+ * @param pszName The name.
+ * @param cchName The length of the name.
+ */
+static bool isInterestingName(const char *pszName, size_t cchName)
+{
+ static struct { const char *psz; size_t cch; } const s_aNames[] =
+ {
+ RT_STR_TUPLE("ntoskrnl.pdb"),
+ RT_STR_TUPLE("ntkrnlmp.pdb"),
+ RT_STR_TUPLE("ntkrnlpa.pdb"),
+ RT_STR_TUPLE("ntkrpamp.pdb"),
+ };
+
+ if ( cchName == s_aNames[0].cch
+ && (pszName[0] == 'n' || pszName[0] == 'N')
+ && (pszName[1] == 't' || pszName[1] == 'T')
+ )
+ {
+ int i = RT_ELEMENTS(s_aNames);
+ while (i-- > 0)
+ if ( s_aNames[i].cch == cchName
+ && !RTStrICmp(s_aNames[i].psz, pszName))
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Recursively processes relevant files in the specified directory.
+ *
+ * @returns Fully complained exit code.
+ * @param pszDir Pointer to the directory buffer.
+ * @param cchDir The length of pszDir in pszDir.
+ * @param pDirEntry Pointer to the directory buffer.
+ */
+static RTEXITCODE processDirSub(char *pszDir, size_t cchDir, PRTDIRENTRYEX pDirEntry, int iLogDepth)
+{
+ Assert(cchDir > 0); Assert(pszDir[cchDir] == '\0');
+
+ /* Make sure we've got some room in the path, to save us extra work further down. */
+ if (cchDir + 3 >= RTPATH_MAX)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Path too long: '%s'\n", pszDir);
+
+ /* Open directory. */
+ PRTDIR pDir;
+ int rc = RTDirOpen(&pDir, pszDir);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDirOpen failed on '%s': %Rrc\n", pszDir, rc);
+
+ /* Ensure we've got a trailing slash (there is space for it see above). */
+ if (!RTPATH_IS_SEP(pszDir[cchDir - 1]))
+ {
+ pszDir[cchDir++] = RTPATH_SLASH;
+ pszDir[cchDir] = '\0';
+ }
+
+ /*
+ * Process the files and subdirs.
+ */
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ for (;;)
+ {
+ /* Get the next directory. */
+ size_t cbDirEntry = MY_DIRENTRY_BUF_SIZE;
+ rc = RTDirReadEx(pDir, pDirEntry, &cbDirEntry, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+ if (RT_FAILURE(rc))
+ break;
+
+ /* Skip the dot and dot-dot links. */
+ if ( (pDirEntry->cbName == 1 && pDirEntry->szName[0] == '.')
+ || (pDirEntry->cbName == 2 && pDirEntry->szName[0] == '.' && pDirEntry->szName[1] == '.'))
+ continue;
+
+ /* Check length. */
+ if (pDirEntry->cbName + cchDir + 3 >= RTPATH_MAX)
+ {
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Path too long: '%s' in '%.*s'\n", pDirEntry->szName, cchDir, pszDir);
+ break;
+ }
+
+ if (RTFS_IS_FILE(pDirEntry->Info.Attr.fMode))
+ {
+ /*
+ * Process debug info files of interest.
+ */
+ if (isInterestingName(pDirEntry->szName, pDirEntry->cbName))
+ {
+ memcpy(&pszDir[cchDir], pDirEntry->szName, pDirEntry->cbName + 1);
+ RTEXITCODE rcExit2 = processPdb(pszDir);
+ if (rcExit2 != RTEXITCODE_SUCCESS)
+ rcExit = rcExit2;
+ }
+ }
+ else if (RTFS_IS_DIRECTORY(pDirEntry->Info.Attr.fMode))
+ {
+ /*
+ * Recurse into the subdirectory. In order to speed up Win7+
+ * symbol pack traversals, we skip directories with ".pdb" suffixes
+ * unless they match any of the .pdb files we're looking for.
+ *
+ * Note! When we get back pDirEntry will be invalid.
+ */
+ if ( pDirEntry->cbName <= 4
+ || RTStrICmp(&pDirEntry->szName[pDirEntry->cbName - 4], ".pdb")
+ || isInterestingName(pDirEntry->szName, pDirEntry->cbName))
+ {
+ memcpy(&pszDir[cchDir], pDirEntry->szName, pDirEntry->cbName + 1);
+ if (iLogDepth > 0)
+ RTMsgInfo("%s%s ...\n", pszDir, RTPATH_SLASH_STR);
+ RTEXITCODE rcExit2 = processDirSub(pszDir, cchDir + pDirEntry->cbName, pDirEntry, iLogDepth - 1);
+ if (rcExit2 != RTEXITCODE_SUCCESS)
+ rcExit = rcExit2;
+ }
+ }
+ }
+ if (rc != VERR_NO_MORE_FILES)
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDirReadEx failed: %Rrc\npszDir=%.*s", rc, cchDir, pszDir);
+
+ rc = RTDirClose(pDir);
+ if (RT_FAILURE(rc))
+ rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDirClose failed: %Rrc\npszDir=%.*s", rc, cchDir, pszDir);
+ return rcExit;
+}
+
+
+/**
+ * Recursively processes relevant files in the specified directory.
+ *
+ * @returns Fully complained exit code.
+ * @param pszDir The directory to search.
+ */
+static RTEXITCODE processDir(const char *pszDir)
+{
+ char szPath[RTPATH_MAX];
+ int rc = RTPathAbs(pszDir, szPath, sizeof(szPath));
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAbs failed on '%s': %Rrc\n", pszDir, rc);
+
+ union
+ {
+ uint8_t abPadding[MY_DIRENTRY_BUF_SIZE];
+ RTDIRENTRYEX DirEntry;
+ } uBuf;
+ return processDirSub(szPath, strlen(szPath), &uBuf.DirEntry, g_iOptVerbose);
+}
+
+
+int main(int argc, char **argv)
+{
+ int rc = RTR3InitExe(argc, &argv, 0 /*fFlags*/);
+ if (RT_FAILURE(rc))
+ return RTMsgInitFailure(rc);
+
+ RTListInit(&g_SetList);
+
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--force", 'f', RTGETOPT_REQ_NOTHING },
+ { "--output", 'o', RTGETOPT_REQ_STRING },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
+ { "--quiet", 'q', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ const char *pszOutput = "-";
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1,
+ RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (ch)
+ {
+ case 'f':
+ g_fOptForce = true;
+ break;
+
+ case 'v':
+ g_iOptVerbose++;
+ break;
+
+ case 'q':
+ g_iOptVerbose++;
+ break;
+
+ case 'o':
+ pszOutput = ValueUnion.psz;
+ break;
+
+ case 'V':
+ RTPrintf("$Revision: 92629 $");
+ break;
+
+ case 'h':
+ RTPrintf("usage: %s [-v|--verbose] [-q|--quiet] [-f|--force] [-o|--output <file.h>] <dir1|pdb1> [...]\n"
+ " or: %s [-V|--version]\n"
+ " or: %s [-h|--help]\n",
+ argv[0], argv[0], argv[0]);
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ RTEXITCODE rcExit2;
+ if (RTFileExists(ValueUnion.psz))
+ rcExit2 = processPdb(ValueUnion.psz);
+ else
+ rcExit2 = processDir(ValueUnion.psz);
+ if (rcExit2 != RTEXITCODE_SUCCESS)
+ {
+ if (!g_fOptForce)
+ return rcExit2;
+ rcExit = rcExit2;
+ }
+ break;
+ }
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
+ }
+ }
+ if (RTListIsEmpty(&g_SetList))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "No usable debug files found.\n");
+
+ /*
+ * Generate the output.
+ */
+ PRTSTREAM pOut = g_pStdOut;
+ if (strcmp(pszOutput, "-"))
+ {
+ rc = RTStrmOpen(pszOutput, "w", &pOut);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening '%s' for writing: %Rrc\n", pszOutput, rc);
+ }
+
+ generateHeader(pOut);
+
+ if (pOut != g_pStdOut)
+ rc = RTStrmClose(pOut);
+ else
+ rc = RTStrmFlush(pOut);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error %s '%s': %Rrc\n", pszOutput,
+ pOut != g_pStdOut ? "closing" : "flushing", rc);
+ return rcExit;
+}
diff --git a/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp
index 93488765..ac45498b 100644
--- a/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/process-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp
index 8cda329e..46cd1d7a 100644
--- a/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semevent-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp
index 50830f75..3d253c55 100644
--- a/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semeventmulti-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp
index bd3efc87..eabbc3e1 100644
--- a/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semfastmutex-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
index 71e02e35..f7b68c4b 100644
--- a/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp
index d3dad434..00dbd3ed 100644
--- a/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/spinlock-r0drv-nt.cpp
@@ -74,7 +74,7 @@ typedef struct RTSPINLOCKINTERNAL
/** The saved IRQL. */
KIRQL volatile SavedIrql;
/** The saved interrupt flag. */
- uint32_t volatile fIntSaved;
+ RTCCUINTREG volatile fIntSaved;
/** The spinlock creation flags. */
uint32_t fFlags;
/** The NT spinlock structure. */
@@ -140,7 +140,7 @@ RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
{
#ifndef RTSPINLOCK_NT_HACK_NOIRQ
- uint32_t fIntSaved = ASMGetFlags();
+ RTCCUINTREG fIntSaved = ASMGetFlags();
ASMIntDisable();
KeAcquireSpinLock(&pThis->Spinlock, &SavedIrql);
#else
@@ -150,7 +150,7 @@ RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
KeRaiseIrql(DISPATCH_LEVEL, &SavedIrql);
Assert(SavedIrql < DISPATCH_LEVEL);
}
- uint32_t fIntSaved = ASMGetFlags();
+ RTCCUINTREG fIntSaved = ASMGetFlags();
ASMIntDisable();
if (!ASMAtomicCmpXchgU32(&pThis->u32Hack, RTSPINLOCK_NT_HACK_NOIRQ_TAKEN, RTSPINLOCK_NT_HACK_NOIRQ_FREE))
@@ -176,7 +176,7 @@ RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
KIRQL SavedIrql = pThis->SavedIrql;
if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
{
- uint32_t fIntSaved = pThis->fIntSaved;
+ RTCCUINTREG fIntSaved = pThis->fIntSaved;
pThis->fIntSaved = 0;
#ifndef RTSPINLOCK_NT_HACK_NOIRQ
diff --git a/src/VBox/Runtime/r0drv/nt/symdb.h b/src/VBox/Runtime/r0drv/nt/symdb.h
new file mode 100644
index 00000000..3a0f12d5
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/nt/symdb.h
@@ -0,0 +1,85 @@
+/* $Id: symdb.h $ */
+/** @file
+ * IPRT - Internal Header for the NT Ring-0 Driver Symbol DB.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___internal_r0drv_nt_symdb_h
+#define ___internal_r0drv_nt_symdb_h
+
+#include <iprt/types.h>
+
+
+/**
+ * NT Version info.
+ */
+typedef struct RTNTSDBOSVER
+{
+ /** The major version number. */
+ uint8_t uMajorVer;
+ /** The minor version number. */
+ uint8_t uMinorVer;
+ /** Set if checked build, clear if free (retail) build. */
+ uint8_t fChecked : 1;
+ /** Set if multi processor kernel. */
+ uint8_t fSmp : 1;
+ /** The service pack number. */
+ uint8_t uCsdNo : 6;
+ /** The build number. */
+ uint32_t uBuildNo;
+} RTNTSDBOSVER;
+/** Pointer to NT version info. */
+typedef RTNTSDBOSVER *PRTNTSDBOSVER;
+/** Pointer to const NT version info. */
+typedef RTNTSDBOSVER const *PCRTNTSDBOSVER;
+
+
+/**
+ * Compare NT OS version structures.
+ *
+ * @retval 0 if equal
+ * @retval 1 if @a pInfo1 is newer/greater than @a pInfo2
+ * @retval -1 if @a pInfo1 is older/less than @a pInfo2
+ *
+ * @param pInfo1 The first version info structure.
+ * @param pInfo2 The second version info structure.
+ */
+DECLINLINE(int) rtNtOsVerInfoCompare(PCRTNTSDBOSVER pInfo1, PCRTNTSDBOSVER pInfo2)
+{
+ if (pInfo1->uMajorVer != pInfo2->uMajorVer)
+ return pInfo1->uMajorVer > pInfo2->uMajorVer ? 1 : -1;
+ if (pInfo1->uMinorVer != pInfo2->uMinorVer)
+ return pInfo1->uMinorVer > pInfo2->uMinorVer ? 1 : -1;
+ if (pInfo1->uBuildNo != pInfo2->uBuildNo)
+ return pInfo1->uBuildNo > pInfo2->uBuildNo ? 1 : -1;
+ if (pInfo1->uCsdNo != pInfo2->uCsdNo)
+ return pInfo1->uCsdNo > pInfo2->uCsdNo ? 1 : -1;
+ if (pInfo1->fSmp != pInfo2->fSmp)
+ return pInfo1->fSmp > pInfo2->fSmp ? 1 : -1;
+ if (pInfo1->fChecked != pInfo2->fChecked)
+ return pInfo1->fChecked > pInfo2->fChecked ? 1 : -1;
+ return 0;
+}
+
+#endif
+
diff --git a/src/VBox/Runtime/r0drv/nt/symdbdata.h b/src/VBox/Runtime/r0drv/nt/symdbdata.h
new file mode 100644
index 00000000..d23aca8d
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/nt/symdbdata.h
@@ -0,0 +1,2920 @@
+/* $Id: symdbdata.h $ */
+/** @file
+ * IPRT - NT kernel type helpers - Autogenerated, do NOT edit.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___r0drv_nt_symdbdata_h
+#define ___r0drv_nt_symdbdata_h
+
+#include "r0drv/nt/symdb.h"
+
+typedef struct RTNTSDBTYPE_KPRCB
+{
+ uint32_t offQuantumEnd;
+ uint32_t cbQuantumEnd;
+ uint32_t offDpcQueueDepth;
+ uint32_t cbDpcQueueDepth;
+ uint32_t offVendorString;
+ uint32_t cbVendorString;
+} RTNTSDBTYPE_KPRCB;
+
+
+typedef struct RTNTSDBSET
+{
+ RTNTSDBOSVER OsVerInfo;
+ RTNTSDBTYPE_KPRCB KPRCB;
+} RTNTSDBSET;
+typedef RTNTSDBSET const *PCRTNTSDBSET;
+
+
+#ifndef RTNTSDB_NO_DATA
+const RTNTSDBSET g_artNtSdbSets[] =
+{
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_nec98\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en_chk\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en_chk\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_nec98\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_nec98\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en_chk\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp3sym_en_chk\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-x86-Symbols-ENU\symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-x86-Symbols-ENU\symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_nec98\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-nec98-Symbols-JPN\symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-nec98-Symbols-JPN\symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en_chk\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en_chk\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-x86-Symbols-ENU\symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-x86-Symbols-ENU\symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_nec98\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_nec98\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-nec98-Symbols-JPN\symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\Windows2000-KB891861-nec98-Symbols-JPN\symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en_chk\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\uold\w2ksp4sym_en_chk\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 4,
+ /* .uBuildNo = */ 2195,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0750,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x06e8,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x072d,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.fre.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.fre.rtm.symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.chk.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.chk.rtm.symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.fre.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.fre.rtm.symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.chk.rtm.symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\windowsxp.x86.chk.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86_chk\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86_chk\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86_chk\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\xpsp1sym_x86_chk\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-slp-Symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-slp-Symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-Debug-slp-Symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-Debug-slp-Symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-slp-Symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-slp-Symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-Debug-slp-Symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB835935-SP2-Debug-slp-Symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-symbols-full-ENU\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-symbols-full-ENU\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-DEBUG-symbols-full-ENU-DEBUG\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-DEBUG-symbols-full-ENU-DEBUG\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-symbols-full-ENU\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-symbols-full-ENU\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-DEBUG-symbols-full-ENU-DEBUG\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsXP-KB936929-SP3-x86-DEBUG-symbols-full-ENU-DEBUG\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 3,
+ /* .uBuildNo = */ 2600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x088c,
+ /* .cbQuantumEnd = */ 0x0004,
+ /* .offDpcQueueDepth = */ 0x0870,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0900,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.fre.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.fre.rtm.symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.chk.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.chk.rtm.symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.fre.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.fre.rtm.symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.chk.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003.x86.chk.rtm.symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x08c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x086c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0a78,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x64-symbols-NRL-ENU\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.fre.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.fre.rtm.symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.amd64.fre.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU-DEBUG\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU-DEBUG\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x64-symbols-NRL-ENU-DEBUG\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.chk.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.chk.rtm.symbols\exe\ntkrnlpa.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.amd64.chk.rtm.symbols\exe\ntoskrnl.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ false,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x64-symbols-NRL-ENU\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.fre.rtm.symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.fre.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.amd64.fre.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU-DEBUG\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x86-symbols-NRL-ENU-DEBUG\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsServer2003-KB933548-v1-x64-symbols-NRL-ENU-DEBUG\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.chk.rtm.symbols\exe\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.x86.chk.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x0981,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x092c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x0b60,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows2003_sp1.amd64.chk.rtm.symbols\exe\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 5,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 3790,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1f75,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x1f18,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x22b4,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6000.061101-2205.x86fre.Symbols\EXE\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 6000,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x19c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x196c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1bac,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6000.061101-2205.x86fre.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 6000,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x19c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x196c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1bac,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\WindowsVista.6000.061101-2205.amd64fre.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 6000,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x3375,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x3318,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x38bc,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6000.061101-2205.x86chk.Symbols\EXE\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 6000,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x19c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x196c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1bac,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6000.061101-2205.x86chk.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 6000,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x19c1,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x196c,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1bac,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\WindowsVista.6000.061101-2205.amd64chk.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 6000,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x3375,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x3318,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x38bc,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Longhorn.6001.080118-1840.x86fre.Symbols\EXE\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 6001,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Longhorn.6001.080118-1840.x86fre.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 6001,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Longhorn.6001.080118-1840.amd64fre.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 6001,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x3475,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x3418,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x399c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Longhorn.6001.080118-1840.x86chk.Symbols\EXE\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 6001,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Longhorn.6001.080118-1840.x86chk.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 6001,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Longhorn.6001.080118-1840.amd64chk.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 6001,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x3475,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x3418,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x399c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6002.090410-1830.x86fre.Symbols\EXE\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 6002,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6002.090410-1830.x86fre.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 6002,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\WindowsVista.6002.090410-1830.amd64fre.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 6002,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x3475,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x3418,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x399c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6002.090410-1830.x86chk.Symbols\EXE\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 6002,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\WindowsVista.6002.090410-1830.x86chk.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 6002,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1a41,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x19ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x1c2c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\WindowsVista.6002.090410-1830.amd64chk.Symbols\EXE\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 0,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 2,
+ /* .uBuildNo = */ 6002,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x3475,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x3418,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x399c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7.7600.16385.090713-1255.X86FRE.Symbols\Symbols\ntkrpamp.pdb\5B308B4ED6464159B87117C711E7340C2\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 7600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7.7600.16385.090713-1255.X86FRE.Symbols\Symbols\ntkrnlmp.pdb\998A3472EEA6405CB8C089DE868F26222\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 7600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Win7.7600.16385.090713-1255.X64FRE.Symbols\Symbols\ntkrnlmp.pdb\F8E2A8B5C9B74BF4A6E4A48F180099942\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 7600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x21d9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2198,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x4bb8,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7.7600.16385.090713-1255.X86CHK.Symbols\Symbols\ntkrnlmp.pdb\9E7882E37C3E4AC9BB60F4EAD9DB492A1\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 7600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7.7600.16385.090713-1255.X86CHK.Symbols\Symbols\ntkrpamp.pdb\3269AC66C11B41FC995991F129E95D5C1\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 7600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Win7.7600.16385.090713-1255.X64CHK.Symbols\Symbols\ntkrnlmp.pdb\C491E3167994497FA91338D08A7787041\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 7600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x21d9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2198,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x4bb8,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7SP1.7601.17514.101119-1850.X86FRE.Symbols\Symbols\ntkrpamp.pdb\684DA42A30CC450F81C535B4D18944B12\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 7601,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7SP1.7601.17514.101119-1850.X86FRE.Symbols\Symbols\ntkrnlmp.pdb\00625D7D36754CBEBA4533BA9A0F3FE22\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 7601,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Win7SP1.7601.17514.101119-1850.AMD64FRE.Symbols\Symbols\ntkrnlmp.pdb\3844DBB920174967BE7AA4A2C20430FA2\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 7601,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x21d9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2198,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x4bb8,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7SP1.7601.17514.101119-1850.X86CHK.Symbols\Symbols\ntkrpamp.pdb\C3355A163C47464183D85DE0B836F83A1\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 7601,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win7SP1.7601.17514.101119-1850.X86CHK.Symbols\Symbols\ntkrnlmp.pdb\1477BEA3E003427CB248D5233B0601951\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 7601,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x1931,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x18ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x336c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Win7SP1.7601.17514.101119-1850.AMD64CHK.Symbols\Symbols\ntkrnlmp.pdb\FF0DE75C807A4B85A7668D2113A62EF11\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 1,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 1,
+ /* .uBuildNo = */ 7601,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x21d9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2198,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x4bb8,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win8.9200.16384.120725-1247.X86FRE.Symbols\Symbols\ntkrpamp.pdb\E2342527EA214C109CD28A19ED4FBCCE2\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9200,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2231,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x21ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x3c7c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Win8.9200.16384.120725-1247.x64FRE.Symbols\Symbols\ntkrnlmp.pdb\724821001C1C4A03AED8C4C71C2E8D1D2\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9200,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2dd9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2d98,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x5948,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\Windows_Win8.9200.16384.120725-1247.X86CHK.Symbols\Symbols\ntkrpamp.pdb\C4F414C9D1854DE495BDAD814A722C4D1\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9200,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2231,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x21ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x3c7c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\Windows_Win8.9200.16384.120725-1247.x64CHK.Symbols\Symbols\ntkrnlmp.pdb\FC0361C3243D459496EE02EF1A7ACD271\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 2,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9200,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2dd9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2d98,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x5948,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\en_windows_8_1_symbols_x86_2712593\ntkrpamp.pdb\9DC1F995475C456C8D1AA9606E3106931\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 3,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2239,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x21ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x3c7c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\en_windows_8_1_symbols_x64_2712576\ntkrnlmp.pdb\A9BBA3C139724A738BE17665DB4393CA1\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 3,
+ /* .fChecked = */ false,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2de9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2d98,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x5958,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_X86
+ { /* Source: s:\WinSyms\u\en_windows_8_1_symbols_debug_checked_x86_2712583\ntkrpamp.pdb\77DAB075113647B5888133D3F79B7B171\ntkrpamp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 3,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2239,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x21ec,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x3c7c,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+# ifdef RT_ARCH_AMD64
+ { /* Source: s:\WinSyms\u\en_windows_8_1_symbols_debug_checked_x64_2712568\ntkrnlmp.pdb\4C5FFE3E839647C5B9471D0C8F9710E11\ntkrnlmp.pdb */
+ /*.OsVerInfo = */
+ {
+ /* .uMajorVer = */ 6,
+ /* .uMinorVer = */ 3,
+ /* .fChecked = */ true,
+ /* .fSmp = */ true,
+ /* .uCsdNo = */ 0,
+ /* .uBuildNo = */ 9600,
+ },
+ /* .KPRCB = */
+ {
+ /* .offQuantumEnd = */ 0x2de9,
+ /* .cbQuantumEnd = */ 0x0001,
+ /* .offDpcQueueDepth = */ 0x2d98,
+ /* .cbDpcQueueDepth = */ 0x0004,
+ /* .offVendorString = */ 0x5958,
+ /* .cbVendorString = */ 0x000d,
+ },
+ },
+# endif
+};
+#endif /* !RTNTSDB_NO_DATA */
+
+
+#endif
+
diff --git a/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h b/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h
index f84e515b..44a805ba 100644
--- a/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h
+++ b/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
index 6bd17558..e16a0f8f 100644
--- a/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -106,6 +106,7 @@ RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
/*
* Read the globals and check if they are useful.
*/
+/** @todo Should we check KPRCB.InterruptRequest and KPRCB.DpcInterruptRequested (older kernels). */
uint32_t const offQuantumEnd = g_offrtNtPbQuantumEnd;
uint32_t const cbQuantumEnd = g_cbrtNtPbQuantumEnd;
uint32_t const offDpcQueueDepth = g_offrtNtPbDpcQueueDepth;
@@ -159,10 +160,14 @@ RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
{
+#if 0 /** @todo RTThreadPreemptIsPending isn't good enough on w7 and possibly elsewhere. */
/* RTThreadPreemptIsPending is only reliable if we've got both offsets and size. */
return g_offrtNtPbQuantumEnd != 0
&& g_cbrtNtPbQuantumEnd != 0
&& g_offrtNtPbDpcQueueDepth != 0;
+#else
+ return false;
+#endif
}
diff --git a/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
index 855a8549..4863194b 100644
--- a/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
index 965f2cbb..938cc7c1 100644
--- a/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007 Oracle Corporation
+ * Copyright (C) 2007-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -35,10 +35,24 @@
DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
{
-#ifndef IPRT_TARGET_NT4
+ /*
+ * Note! The time source we use here must be exactly the same as in
+ * the ring-3 code!
+ *
+ * Using interrupt time is the simplest and requires the least calculation.
+ * It is also accounting for suspended time. Unfortuantely, there is no
+ * ring-3 for reading it... but that won't stop us.
+ *
+ * Using the tick count is problematic in ring-3 on older windows version
+ * as we can only get the 32-bit tick value, i.e. we'll roll over sooner or
+ * later.
+ */
+#if 1
+ /* Interrupt time. (NT4 doesn't have an API for it.) */
+# ifndef IPRT_TARGET_NT4
ULONGLONG InterruptTime = KeQueryInterruptTime();
return (uint64_t)InterruptTime * 100; /* The value is in 100ns, convert to ns units. */
-#else
+# else
LARGE_INTEGER InterruptTime;
do
{
@@ -47,6 +61,12 @@ DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
} while (((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High2Time != InterruptTime.HighPart);
return (uint64_t)InterruptTime.QuadPart * 100;
+# endif
+#else
+ /* Tick Count (NT4 SP1 has these APIs, haven't got SP0 to check). */
+ LARGE_INTEGER Tick;
+ KeQueryTickCount(&Tick);
+ return (uint64_t)Tick.QuadPart * KeQueryTimeIncrement() * 100;
#endif
}
diff --git a/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
index ee014310..67764b62 100644
--- a/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -121,7 +121,11 @@ static void _stdcall rtTimerNtSimpleCallback(IN PKDPC pDpc, IN PVOID pvUser, IN
*/
if ( !ASMAtomicUoReadBool(&pTimer->fSuspended)
&& pTimer->u32Magic == RTTIMER_MAGIC)
+ {
+ if (!pTimer->u64NanoInterval)
+ ASMAtomicWriteBool(&pTimer->fSuspended, true);
pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->aSubTimers[0].iTick);
+ }
NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2);
}
@@ -154,7 +158,11 @@ static void _stdcall rtTimerNtOmniSlaveCallback(IN PKDPC pDpc, IN PVOID pvUser,
*/
if ( !ASMAtomicUoReadBool(&pTimer->fSuspended)
&& pTimer->u32Magic == RTTIMER_MAGIC)
+ {
+ if (!pTimer->u64NanoInterval)
+ ASMAtomicWriteBool(&pTimer->fSuspended, true);
pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
+ }
NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2);
}
@@ -199,6 +207,8 @@ static void _stdcall rtTimerNtOmniMasterCallback(IN PKDPC pDpc, IN PVOID pvUser,
&& iCpuSelf != iCpu)
KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0);
+ if (!pTimer->u64NanoInterval)
+ ASMAtomicWriteBool(&pTimer->fSuspended, true);
pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
}
@@ -237,9 +247,12 @@ RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
LARGE_INTEGER DueTime;
DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */
- if (DueTime.QuadPart)
+ if (!DueTime.QuadPart)
DueTime.QuadPart = -1;
+ unsigned cSubTimers = pTimer->fOmniTimer ? pTimer->cSubTimers : 1;
+ for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++)
+ pTimer->aSubTimers[iCpu].iTick = 0;
ASMAtomicWriteBool(&pTimer->fSuspended, false);
KeSetTimerEx(&pTimer->NtTimer, DueTime, ulInterval, pMasterDpc);
return VINF_SUCCESS;
diff --git a/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp
index ea58e623..0a596bbd 100644
--- a/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/memuserkernel-r0drv-os2.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
index e597ad45..0dc74266 100644
--- a/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
@@ -181,8 +181,8 @@ static int rtR0SemEventOs2Wait(PRTSEMEVENTINTERNAL pThis, uint32_t fFlags, uint6
ULONG fBlock = BLOCK_SPINLOCK;
if (!(fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE))
fBlock |= BLOCK_UNINTERRUPTABLE;
-
- /*
+
+ /*
* Do the job.
*/
KernAcquireSpinLock(&pThis->Spinlock);
diff --git a/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp
index ea0bda5d..ae06e211 100644
--- a/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/semeventmulti-r0drv-os2.cpp
@@ -192,8 +192,8 @@ static int rtR0SemEventMultiOs2Wait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFl
ULONG fBlock = BLOCK_SPINLOCK;
if (!(fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE))
fBlock |= BLOCK_UNINTERRUPTABLE;
-
- /*
+
+ /*
* Do the job.
*/
KernAcquireSpinLock(&pThis->Spinlock);
diff --git a/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp b/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp
index 531e88f6..39be522a 100644
--- a/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp
+++ b/src/VBox/Runtime/r0drv/os2/spinlock-r0drv-os2.cpp
@@ -38,6 +38,9 @@
#include <iprt/alloc.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
+#ifdef RT_STRICT
+# include <iprt/asm-amd64-x86.h>
+#endif
#include "internal/magics.h"
diff --git a/src/VBox/Runtime/r0drv/power-r0drv.h b/src/VBox/Runtime/r0drv/power-r0drv.h
index a10c4c1e..ba1ada04 100644
--- a/src/VBox/Runtime/r0drv/power-r0drv.h
+++ b/src/VBox/Runtime/r0drv/power-r0drv.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/powernotification-r0drv.c b/src/VBox/Runtime/r0drv/powernotification-r0drv.c
index 138e5c4b..87d73d0f 100644
--- a/src/VBox/Runtime/r0drv/powernotification-r0drv.c
+++ b/src/VBox/Runtime/r0drv/powernotification-r0drv.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c
index 0414bcd4..34718740 100644
--- a/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/RTLogWriteDebugger-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -37,6 +37,7 @@
# include <iprt/asm-amd64-x86.h>
#endif
#include <iprt/assert.h>
+#include <iprt/thread.h>
@@ -44,6 +45,11 @@ RTDECL(void) RTLogWriteDebugger(const char *pch, size_t cb)
{
if (pch[cb] != '\0')
AssertBreakpoint();
+
+ /* cmn_err() acquires adaptive mutexes. Not preemption safe, see @bugref{6657}. */
+ if (!RTThreadPreemptIsEnabled(NIL_RTTHREAD))
+ return;
+
if ( !g_frtSolSplSetsEIF
#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
|| ASMIntAreEnabled()
@@ -51,7 +57,10 @@ RTDECL(void) RTLogWriteDebugger(const char *pch, size_t cb)
/* PORTME: Check if interrupts are enabled, if applicable. */
#endif
)
+ {
cmn_err(CE_CONT, pch);
+ }
+
return;
}
diff --git a/src/VBox/Runtime/r0drv/solaris/RTMpPokeCpu-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/RTMpPokeCpu-r0drv-solaris.c
index 60e75765..eb49b625 100644
--- a/src/VBox/Runtime/r0drv/solaris/RTMpPokeCpu-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/RTMpPokeCpu-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/alloc-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/alloc-r0drv-solaris.c
index 83013b8b..fc31009d 100644
--- a/src/VBox/Runtime/r0drv/solaris/alloc-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/alloc-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -73,7 +73,7 @@ DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
#ifdef RT_ARCH_AMD64
if (fFlags & RTMEMHDR_FLAG_EXEC)
{
- AssertReturn(!(fFlags & RTMEMHDR_FLAG_ANY_CTX), NULL);
+ AssertReturn(!(fFlags & RTMEMHDR_FLAG_ANY_CTX), VERR_NOT_SUPPORTED);
cbAllocated = RT_ALIGN_Z(cb + sizeof(*pHdr), PAGE_SIZE) - sizeof(*pHdr);
pHdr = (PRTMEMHDR)segkmem_alloc(heaptext_arena, cbAllocated + sizeof(*pHdr), KM_SLEEP);
}
diff --git a/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c
index ce6fe0dd..823c18aa 100644
--- a/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/assert-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
index 3fa8dbea..0d435364 100644
--- a/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -66,6 +66,10 @@ bool g_frtSolOldIPI = false;
bool g_frtSolOldIPIUlong = false;
/** The xc_call callout table structure. */
RTR0FNSOLXCCALL g_rtSolXcCall;
+/** Whether to use the old-style installctx()/removectx() routines. */
+bool g_frtSolOldThreadCtx = false;
+/** The thread-context hooks callout table structure. */
+RTR0FNSOLTHREADCTX g_rtSolThreadCtx;
/** Thread preemption offset. */
size_t g_offrtSolThreadPreempt;
/** Host scheduler preemption offset. */
@@ -126,9 +130,9 @@ DECLHIDDEN(int) rtR0InitNative(void)
cmn_err(CE_NOTE, "Failed to find kthread_t::t_preempt!\n");
goto errorbail;
}
- cmn_err(CE_CONT, "!cpu_t::cpu_runrun @ 0x%lx\n", g_offrtSolCpuPreempt);
- cmn_err(CE_CONT, "!cpu_t::cpu_kprunrun @ 0x%lx\n", g_offrtSolCpuForceKernelPreempt);
- cmn_err(CE_CONT, "!kthread_t::t_preempt @ 0x%lx\n", g_offrtSolThreadPreempt);
+ cmn_err(CE_CONT, "!cpu_t::cpu_runrun @ 0x%lx (%ld)\n", g_offrtSolCpuPreempt, g_offrtSolCpuPreempt);
+ cmn_err(CE_CONT, "!cpu_t::cpu_kprunrun @ 0x%lx (%ld)\n", g_offrtSolCpuForceKernelPreempt, g_offrtSolCpuForceKernelPreempt);
+ cmn_err(CE_CONT, "!kthread_t::t_preempt @ 0x%lx (%ld)\n", g_offrtSolThreadPreempt, g_offrtSolThreadPreempt);
/*
* Mandatory: CPU cross call infrastructure. Refer the-solaris-kernel.h for details.
@@ -163,6 +167,22 @@ DECLHIDDEN(int) rtR0InitNative(void)
}
/*
+ * Mandatory: Thread-context hooks.
+ */
+ rc = RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "exitctx", NULL /* ppvSymbol */);
+ if (RT_SUCCESS(rc))
+ {
+ g_rtSolThreadCtx.Install.pfnSol_installctx = (void *)installctx;
+ g_rtSolThreadCtx.Remove.pfnSol_removectx = (void *)removectx;
+ }
+ else
+ {
+ g_frtSolOldThreadCtx = true;
+ g_rtSolThreadCtx.Install.pfnSol_installctx_old = (void *)installctx;
+ g_rtSolThreadCtx.Remove.pfnSol_removectx_old = (void *)removectx;
+ }
+
+ /*
* Optional: Timeout hooks.
*/
RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "timeout_generic",
diff --git a/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c
index 68741df0..b5e0ee6f 100644
--- a/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c
@@ -143,6 +143,10 @@ static page_t *rtR0MemObjSolPageAlloc(caddr_t virtAddr)
u_offset_t offPage;
seg_t KernelSeg;
+ /*
+ * 16777215 terabytes of total memory for all VMs or
+ * restart 8000 1GB VMs 2147483 times until wraparound!
+ */
mutex_enter(&g_OffsetMtx);
AssertCompileSize(u_offset_t, sizeof(uint64_t)); NOREF(RTASSERTVAR);
g_offPage = RT_ALIGN_64(g_offPage, PAGE_SIZE) + PAGE_SIZE;
@@ -968,7 +972,7 @@ DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ
size_t off = 0;
while (off < cbSub)
{
- RTHCPHYS HCPhys = rtR0MemObjNativeGetPagePhysAddr(pMemToMap, (offSub + offSub) >> PAGE_SHIFT);
+ RTHCPHYS HCPhys = RTR0MemObjGetPagePhysAddr(pMemToMap, (offSub + offSub) >> PAGE_SHIFT);
AssertBreakStmt(HCPhys != NIL_RTHCPHYS, rc = VERR_INTERNAL_ERROR_2);
pfn_t pfn = HCPhys >> PAGE_SHIFT;
AssertBreakStmt(((RTHCPHYS)pfn << PAGE_SHIFT) == HCPhys, rc = VERR_INTERNAL_ERROR_3);
diff --git a/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c
index bb16c9b0..4e1e8183 100644
--- a/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/memuserkernel-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/mp-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/mp-r0drv-solaris.c
index fb3b8c28..3a9dce99 100644
--- a/src/VBox/Runtime/r0drv/solaris/mp-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/mp-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -136,9 +136,9 @@ RTDECL(RTCPUID) RTMpGetOnlineCount(void)
/**
* Wrapper to Solaris IPI infrastructure.
*
- * @param pCpuSet Pointer to Solaris CPU set.
- * @param pfnSolWorker Function to execute on target CPU(s).
- * @param pArgs Pointer to RTMPARGS to pass to @a pfnSolWorker.
+ * @param pCpuSet Pointer to Solaris CPU set.
+ * @param pfnSolWorker Function to execute on target CPU(s).
+ * @param pArgs Pointer to RTMPARGS to pass to @a pfnSolWorker.
*
* @returns Solaris error code.
*/
diff --git a/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c
index fcfb286d..a7c1f9b6 100644
--- a/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/process-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/process-r0drv-solaris.c
index f5c46121..2b4a96af 100644
--- a/src/VBox/Runtime/r0drv/solaris/process-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/process-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
index f52bd57c..5c902bfa 100644
--- a/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
index bec1b4ef..00aa7f00 100644
--- a/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h b/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h
index 2e68644a..042cfd8d 100644
--- a/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h
+++ b/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c
index baeaec2f..3329a562 100644
--- a/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semfastmutex-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
index ceb0f21f..2a7925d5 100644
--- a/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/semmutex-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c
index 3b671ffb..bae81d1d 100644
--- a/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/spinlock-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h b/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
index 2ab935f5..0a5a1ad0 100644
--- a/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
+++ b/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -57,6 +57,7 @@
#include <sys/kobj.h>
#include <sys/ctf_api.h>
#include <sys/modctl.h>
+#include <sys/proc.h>
#undef u /* /usr/include/sys/user.h:249:1 is where this is defined to (curproc->p_user). very cool. */
@@ -146,6 +147,52 @@ extern RTR0FNSOLXCCALL g_rtSolXcCall;
extern bool g_frtSolOldIPI;
extern bool g_frtSolOldIPIUlong;
+/*
+ * Thread-context hooks.
+ * Workarounds for older Solaris versions that did not have the exitctx() callback.
+ */
+typedef struct RTR0FNSOLTHREADCTX
+{
+ union
+ {
+ void *(*pfnSol_installctx) (kthread_t *pThread, void *pvArg,
+ void (*pfnSave)(void *pvArg),
+ void (*pfnRestore)(void *pvArg),
+ void (*pfnFork)(void *pvThread, void *pvThreadFork),
+ void (*pfnLwpCreate)(void *pvThread, void *pvThreadCreate),
+ void (*pfnExit)(void *pvThread),
+ void (*pfnFree)(void *pvArg, int fIsExec));
+
+ void *(*pfnSol_installctx_old) (kthread_t *pThread, void *pvArg,
+ void (*pfnSave)(void *pvArg),
+ void (*pfnRestore)(void *pvArg),
+ void (*pfnFork)(void *pvThread, void *pvThreadFork),
+ void (*pfnLwpCreate)(void *pvThread, void *pvThreadCreate),
+ void (*pfnFree)(void *pvArg, int fIsExec));
+ } Install;
+
+ union
+ {
+ int (*pfnSol_removectx) (kthread_t *pThread, void *pvArg,
+ void (*pfnSave)(void *pvArg),
+ void (*pfnRestore)(void *pvArg),
+ void (*pfnFork)(void *pvThread, void *pvThreadFork),
+ void (*pfnLwpCreate)(void *pvThread, void *pvThreadCreate),
+ void (*pfnExit)(void *pvThread),
+ void (*pfnFree)(void *pvArg, int fIsExec));
+
+ int (*pfnSol_removectx_old) (kthread_t *pThread, void *pvArg,
+ void (*pfnSave)(void *pvArg),
+ void (*pfnRestore)(void *pvArg),
+ void (*pfnFork)(void *pvThread, void *pvThreadFork),
+ void (*pfnLwpCreate)(void *pvThread, void *pvThreadCreate),
+ void (*pfnFree)(void *pvArg, int fIsExec));
+ } Remove;
+} RTR0FNSOLTHREADCTX;
+typedef RTR0FNSOLTHREADCTX *PRTR0FNSOLTHREADCTX;
+
+extern RTR0FNSOLTHREADCTX g_rtSolThreadCtx;
+extern bool g_frtSolOldThreadCtx;
/* Solaris globals. */
extern uintptr_t kernelbase;
diff --git a/src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c
index c495133b..9983ba28 100644
--- a/src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/thread2-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/thread2-r0drv-solaris.c
index 4200aaef..d8f04b11 100644
--- a/src/VBox/Runtime/r0drv/solaris/thread2-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/thread2-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c
new file mode 100644
index 00000000..3f5b507c
--- /dev/null
+++ b/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c
@@ -0,0 +1,337 @@
+/* $Id: threadctxhooks-r0drv-solaris.c $ */
+/** @file
+ * IPRT - Thread-Context Hook, Ring-0 Driver, Solaris.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "the-solaris-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/mem.h>
+#include <iprt/assert.h>
+#include <iprt/thread.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/log.h>
+#include "internal/thread.h"
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * The internal thread-context object.
+ */
+typedef struct RTTHREADCTXINT
+{
+ /** Magic value (RTTHREADCTXINT_MAGIC). */
+ uint32_t volatile u32Magic;
+ /** The thread handle (owner) for which the context-hooks are registered. */
+ RTNATIVETHREAD hOwner;
+ /** Pointer to the registered thread-context hook. */
+ PFNRTTHREADCTXHOOK pfnThreadCtxHook;
+ /** User argument passed to the thread-context hook. */
+ void *pvUser;
+ /** Whether this handle has any hooks registered or not. */
+ bool volatile fRegistered;
+ /** Number of references to this object. */
+ uint32_t volatile cRefs;
+} RTTHREADCTXINT, *PRTTHREADCTXINT;
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** Validates a thread-context hook handle and returns rc if not valid. */
+#define RTTHREADCTX_VALID_RETURN_RC(pThis, rc) \
+ do { \
+ AssertPtrReturn((pThis), (rc)); \
+ AssertReturn((pThis)->u32Magic == RTTHREADCTXINT_MAGIC, (rc)); \
+ AssertReturn((pThis)->cRefs > 0, (rc)); \
+ } while (0)
+
+
+/**
+ * Hook function for the thread-preempting event.
+ *
+ * @param pvThreadCtxInt Opaque pointer to the internal thread-context
+ * object.
+ *
+ * @remarks Called with the with preemption disabled!
+ */
+static void rtThreadCtxHooksSolPreempting(void *pvThreadCtxInt)
+{
+ PRTTHREADCTXINT pThis = (PRTTHREADCTXINT)pvThreadCtxInt;
+ AssertPtr(pThis);
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ if (pThis->fRegistered)
+ {
+ Assert(pThis->pfnThreadCtxHook);
+ pThis->pfnThreadCtxHook(RTTHREADCTXEVENT_PREEMPTING, pThis->pvUser);
+ }
+}
+
+
+/**
+ * Hook function for the thread-resumed event.
+ *
+ * @param pvThreadCtxInt Opaque pointer to the internal thread-context
+ * object.
+ */
+static void rtThreadCtxHooksSolResumed(void *pvThreadCtxInt)
+{
+ PRTTHREADCTXINT pThis = (PRTTHREADCTXINT)pvThreadCtxInt;
+ AssertPtr(pThis);
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ if (pThis->fRegistered)
+ {
+ Assert(pThis->pfnThreadCtxHook);
+ pThis->pfnThreadCtxHook(RTTHREADCTXEVENT_RESUMED, pThis->pvUser);
+ }
+}
+
+
+/**
+ * Hook function for the thread-free event.
+ *
+ * @param pvThreadCtxInt Opaque pointer to the internal thread-context
+ * object.
+ * @param fIsExec Whether this event is triggered due to exec().
+ */
+static void rtThreadCtxHooksSolFree(void *pvThreadCtxInt, int fIsExec)
+{
+ PRTTHREADCTXINT pThis = (PRTTHREADCTXINT)pvThreadCtxInt;
+ AssertPtrReturnVoid(pThis);
+ AssertMsgReturnVoid(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis));
+
+ uint32_t cRefs = ASMAtomicReadU32(&pThis->cRefs);
+ if (RT_UNLIKELY(!cRefs))
+ {
+ /* Should never happen. */
+ AssertMsgFailed(("rtThreadCtxHooksSolFree with cRefs=0 pThis=%p\n", pThis));
+ return;
+ }
+
+ cRefs = ASMAtomicDecU32(&pThis->cRefs);
+ if (!cRefs)
+ {
+ Assert(!pThis->fRegistered);
+ ASMAtomicWriteU32(&pThis->u32Magic, ~RTTHREADCTXINT_MAGIC);
+ RTMemFree(pThis);
+ }
+}
+
+
+RTDECL(int) RTThreadCtxHooksCreate(PRTTHREADCTX phThreadCtx)
+{
+ PRTTHREADCTXINT pThis;
+ Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ pThis = (PRTTHREADCTXINT)RTMemAllocZ(sizeof(*pThis));
+ if (RT_UNLIKELY(!pThis))
+ return VERR_NO_MEMORY;
+ pThis->u32Magic = RTTHREADCTXINT_MAGIC;
+ pThis->hOwner = RTThreadNativeSelf();
+ pThis->fRegistered = false;
+ pThis->cRefs = 2; /* One reference for the thread, one for the hook object. */
+
+ /*
+ * installctx() allocates memory and thus cannot be used in RTThreadCtxHooksRegister() which can be used
+ * with preemption disabled. We allocate the context-hooks here and use 'fRegistered' to determine if we can
+ * invoke the consumer's hook or not.
+ */
+ if (g_frtSolOldThreadCtx)
+ {
+ g_rtSolThreadCtx.Install.pfnSol_installctx_old(curthread,
+ pThis,
+ rtThreadCtxHooksSolPreempting,
+ rtThreadCtxHooksSolResumed,
+ NULL, /* fork */
+ NULL, /* lwp_create */
+ rtThreadCtxHooksSolFree);
+ }
+ else
+ {
+ g_rtSolThreadCtx.Install.pfnSol_installctx(curthread,
+ pThis,
+ rtThreadCtxHooksSolPreempting,
+ rtThreadCtxHooksSolResumed,
+ NULL, /* fork */
+ NULL, /* lwp_create */
+ NULL, /* exit */
+ rtThreadCtxHooksSolFree);
+ }
+
+ *phThreadCtx = pThis;
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRetain(RTTHREADCTX hThreadCtx)
+{
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ RTTHREADCTX_VALID_RETURN_RC(hThreadCtx, UINT32_MAX);
+
+ uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+ Assert(cRefs < UINT32_MAX / 2);
+ return cRefs;
+}
+
+
+RTDECL(uint32_t) RTThreadCtxHooksRelease(RTTHREADCTX hThreadCtx)
+{
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return 0;
+
+ RTTHREADCTX_VALID_RETURN_RC(hThreadCtx, UINT32_MAX);
+ Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+ ASMAtomicWriteBool(&pThis->fRegistered, false);
+ uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+
+ if ( cRefs == 1
+ && pThis->hOwner == RTThreadNativeSelf())
+ {
+ /*
+ * removectx() will invoke rtThreadCtxHooksSolFree() and there is no way to bypass it and still use
+ * rtThreadCtxHooksSolFree() at the same time. Hence the convulated reference counting.
+ *
+ * When this function is called from the owner thread and is the last reference, we call removectx() which
+ * will invoke rtThreadCtxHooksSolFree() with cRefs = 1 and that will then free the hook object.
+ *
+ * When the function is called from a different thread, we simply decrement the reference. Whenever the
+ * ring-0 thread dies, Solaris will call rtThreadCtxHooksSolFree() which will free the hook object.
+ */
+ int rc;
+ if (g_frtSolOldThreadCtx)
+ {
+ rc = g_rtSolThreadCtx.Remove.pfnSol_removectx_old(curthread,
+ pThis,
+ rtThreadCtxHooksSolPreempting,
+ rtThreadCtxHooksSolResumed,
+ NULL, /* fork */
+ NULL, /* lwp_create */
+ rtThreadCtxHooksSolFree);
+ }
+ else
+ {
+ rc = g_rtSolThreadCtx.Remove.pfnSol_removectx(curthread,
+ pThis,
+ rtThreadCtxHooksSolPreempting,
+ rtThreadCtxHooksSolResumed,
+ NULL, /* fork */
+ NULL, /* lwp_create */
+ NULL, /* exit */
+ rtThreadCtxHooksSolFree);
+ }
+ AssertMsg(rc, ("removectx() failed. rc=%d\n", rc));
+ NOREF(rc);
+
+#ifdef VBOX_STRICT
+ cRefs = ASMAtomicReadU32(&pThis->cRefs);
+ Assert(!cRefs);
+#endif
+ cRefs = 0;
+ }
+ else if (!cRefs)
+ {
+ /*
+ * The ring-0 thread for this hook object has already died. Free up the object as we have no more references.
+ */
+ Assert(pThis->hOwner != RTThreadNativeSelf());
+ ASMAtomicWriteU32(&pThis->u32Magic, ~RTTHREADCTXINT_MAGIC);
+ RTMemFree(pThis);
+ }
+
+ return cRefs;
+}
+
+
+RTDECL(int) RTThreadCtxHooksRegister(RTTHREADCTX hThreadCtx, PFNRTTHREADCTXHOOK pfnThreadCtxHook, void *pvUser)
+{
+ /*
+ * Validate input.
+ */
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return VERR_INVALID_HANDLE;
+ AssertPtr(pThis);
+ AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
+ VERR_INVALID_HANDLE);
+ Assert(pThis->hOwner == RTThreadNativeSelf());
+
+ /*
+ * Register the callback.
+ */
+ pThis->pvUser = pvUser;
+ pThis->pfnThreadCtxHook = pfnThreadCtxHook;
+ pThis->fRegistered = true;
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTThreadCtxHooksDeregister(RTTHREADCTX hThreadCtx)
+{
+ /*
+ * Validate input.
+ */
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return VERR_INVALID_HANDLE;
+ AssertPtr(pThis);
+ AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
+ VERR_INVALID_HANDLE);
+ Assert(pThis->hOwner == RTThreadNativeSelf());
+ Assert(pThis->fRegistered);
+
+ /*
+ * Deregister the callback.
+ */
+ pThis->fRegistered = false;
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+ /*
+ * Validate input.
+ */
+ PRTTHREADCTXINT pThis = hThreadCtx;
+ if (pThis == NIL_RTTHREADCTX)
+ return false;
+ AssertPtr(pThis);
+ AssertMsg(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis));
+
+ return pThis->fRegistered;
+}
+
diff --git a/src/VBox/Runtime/r0drv/solaris/time-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/time-r0drv-solaris.c
index 263c59ac..d4113ace 100644
--- a/src/VBox/Runtime/r0drv/solaris/time-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/time-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c b/src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c
index 2fec4db6..dd612015 100644
--- a/src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c
+++ b/src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -124,6 +124,36 @@ typedef struct RTTIMER
/**
+ * Callback wrapper for specific timers if they happened to have been fired on
+ * the wrong CPU. See rtTimerSolCallbackWrapper().
+ *
+ * @param idCpu The CPU this is fired on.
+ * @param pvUser1 Opaque pointer to the timer.
+ * @param pvUser2 Not used, NULL.
+ */
+static void rtTimerSolMpCallbackWrapper(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+ PRTTIMER pTimer = (PRTTIMER)pvUser1;
+ AssertPtrReturnVoid(pTimer);
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+ Assert(pTimer->iCpu == RTMpCpuId()); /* ASSUMES: index == cpuid */
+ Assert(pTimer->pSingleTimer);
+ NOREF(pvUser2);
+
+ /* Make sure one-shots do not fire another time. */
+ Assert( !pTimer->fSuspended
+ || pTimer->interval != 0);
+
+ /* For one-shot specific timers, allow RTTimer to restart them. */
+ if (pTimer->interval == 0)
+ pTimer->fSuspended = true;
+
+ uint64_t u64Tick = ++pTimer->pSingleTimer->u64Tick;
+ pTimer->pfnTimer(pTimer, pTimer->pvUser, u64Tick);
+}
+
+
+/**
* Callback wrapper for Omni-CPU and single-CPU timers.
*
* @param pvArg Opaque pointer to the timer.
@@ -136,9 +166,27 @@ static void rtTimerSolCallbackWrapper(void *pvArg)
{
PRTTIMER pTimer = (PRTTIMER)pvArg;
AssertPtrReturnVoid(pTimer);
+ Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
if (pTimer->pSingleTimer)
{
+ /* Make sure one-shots do not fire another time. */
+ Assert( !pTimer->fSuspended
+ || pTimer->interval != 0);
+
+ /* For specific timers, we might fire on the wrong CPU between cyclic_add() and cyclic_bind().
+ Redirect these shots to the right CPU as we are temporarily rebinding to the right CPU. */
+ if ( pTimer->fSpecificCpu
+ && pTimer->iCpu != RTMpCpuId()) /* ASSUMES: index == cpuid */
+ {
+ RTMpOnSpecific(pTimer->iCpu, rtTimerSolMpCallbackWrapper, pTimer, NULL);
+ return;
+ }
+
+ /* For one-shot any-cpu timers, allow RTTimer to restart them. */
+ if (pTimer->interval == 0)
+ pTimer->fSuspended = true;
+
uint64_t u64Tick = ++pTimer->pSingleTimer->u64Tick;
pTimer->pfnTimer(pTimer, pTimer->pvUser, u64Tick);
}
@@ -202,8 +250,12 @@ RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_
&& !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK)))
return VERR_CPU_NOT_FOUND;
- if ((fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL && u64NanoInterval == 0)
+ /* One-shot omni timers are not supported by the cyclic system. */
+ if ( (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL
+ && u64NanoInterval == 0)
+ {
return VERR_NOT_SUPPORTED;
+ }
/*
* Allocate and initialize the timer handle.
@@ -269,13 +321,10 @@ RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
if (!pTimer->fSuspended)
return VERR_TIMER_ACTIVE;
- /* One-shot timers are not supported by the cyclic system. */
- if (pTimer->interval == 0)
- return VERR_NOT_SUPPORTED;
-
pTimer->fSuspended = false;
if (pTimer->fAllCpu)
{
+ Assert(pTimer->interval);
PRTR0OMNITIMERSOL pOmniTimer = RTMemAllocZ(sizeof(RTR0OMNITIMERSOL));
if (RT_UNLIKELY(!pOmniTimer))
return VERR_NO_MEMORY;
@@ -323,7 +372,8 @@ RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
pSingleTimer->hHandler.cyh_level = CY_LOCK_LEVEL;
mutex_enter(&cpu_lock);
- if (iCpu != SOL_TIMER_ANY_CPU && !cpu_is_online(cpu[iCpu]))
+ if ( iCpu != SOL_TIMER_ANY_CPU
+ && !cpu_is_online(cpu[iCpu]))
{
mutex_exit(&cpu_lock);
RTMemFree(pSingleTimer);
@@ -334,9 +384,12 @@ RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
pSingleTimer->hFireTime.cyt_when = u64First + RTTimeNanoTS();
if (pTimer->interval == 0)
{
- /** @todo use gethrtime_max instead of LLONG_MAX? */
- AssertCompileSize(pSingleTimer->hFireTime.cyt_interval, sizeof(long long));
- pSingleTimer->hFireTime.cyt_interval = LLONG_MAX - pSingleTimer->hFireTime.cyt_when;
+ /*
+ * cylic_add() comment: "The caller is responsible for assuring that cyt_when + cyt_interval <= INT64_MAX"
+ * but it contradicts itself because cyclic_reprogram() updates only the interval and accepts CY_INFINITY as
+ * a valid, special value. See cyclic_fire().
+ */
+ pSingleTimer->hFireTime.cyt_interval = CY_INFINITY;
}
else
pSingleTimer->hFireTime.cyt_interval = pTimer->interval;