diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Runtime/r0drv | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-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')
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; |