From fb123f93f9f5ce42c8e5785d2f8e0edaf951740e Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Wed, 26 Mar 2014 19:21:20 +0000 Subject: Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2. --- include/Makefile.kmk | 4 +- include/VBox/DevPCNet.h | 99 -- include/VBox/ExtPack/ExtPack.h | 8 +- include/VBox/HGSMI/HGSMI.h | 2 +- include/VBox/HGSMI/HGSMIChSetup.h | 6 +- include/VBox/HGSMI/HGSMIChannels.h | 2 +- include/VBox/Hardware/VBoxVideoVBE.h | 3 +- include/VBox/HostServices/GuestControlSvc.h | 931 +++++++--- include/VBox/HostServices/GuestPropertySvc.h | 2 +- include/VBox/HostServices/Service.h | 2 +- include/VBox/HostServices/VBoxClipboardExt.h | 2 +- include/VBox/HostServices/VBoxClipboardSvc.h | 11 +- include/VBox/HostServices/VBoxCrOpenGLSvc.h | 69 +- include/VBox/HostServices/VBoxHostChannel.h | 9 +- include/VBox/HostServices/VBoxOGLOp.h | 2 +- include/VBox/RemoteDesktop/VRDE.h | 4 +- include/VBox/RemoteDesktop/VRDEImage.h | 9 +- include/VBox/RemoteDesktop/VRDEInput.h | 220 +++ include/VBox/RemoteDesktop/VRDEVideoIn.h | 1078 ++++++++++++ include/VBox/VBoxCrHgsmi.h | 2 +- include/VBox/VBoxDrvCfg-win.h | 2 +- include/VBox/VBoxGL2D.h | 2 +- include/VBox/VBoxGuest.h | 78 +- include/VBox/VBoxGuest.inc | 2 +- include/VBox/VBoxGuest.mac | 2 +- include/VBox/VBoxGuest16.h | 2 +- include/VBox/VBoxGuest2.h | 2 +- include/VBox/VBoxGuestLib.h | 168 +- include/VBox/VBoxNetCfg-win.h | 2 +- include/VBox/VBoxTpG.h | 16 +- include/VBox/VBoxUhgsmi.h | 2 +- include/VBox/VBoxVideo.h | 359 +++- include/VBox/VBoxVideo3D.h | 10 +- include/VBox/VBoxVideoGuest.h | 16 +- include/VBox/VBoxVideoHost3D.h | 128 ++ include/VBox/VDEPlugSymDefs.h | 2 +- include/VBox/VMMDev.h | 143 +- include/VBox/VMMDev2.h | 2 +- include/VBox/apic.h | 37 +- include/VBox/apic.mac | 22 +- include/VBox/asmdefs.mac | 2 +- include/VBox/bioslogo.h | 2 +- include/VBox/cdefs.h | 16 +- include/VBox/com/AutoLock.h | 7 +- include/VBox/com/ErrorInfo.h | 35 +- include/VBox/com/EventQueue.h | 114 +- include/VBox/com/Guid.h | 143 +- include/VBox/com/MultiResult.h | 6 +- include/VBox/com/NativeEventQueue.h | 140 ++ include/VBox/com/VirtualBox.h | 26 +- include/VBox/com/array.h | 80 +- include/VBox/com/assert.h | 6 +- include/VBox/com/com.h | 3 +- include/VBox/com/defs.h | 90 +- include/VBox/com/errorprint.h | 9 +- include/VBox/com/list.h | 46 +- include/VBox/com/listeners.h | 3 +- include/VBox/com/mtlist.h | 32 +- include/VBox/com/ptr.h | 6 +- include/VBox/com/string.h | 24 +- include/VBox/dbg.h | 92 +- include/VBox/dbggui.h | 8 +- include/VBox/dbus-calls.h | 14 +- include/VBox/dbus.h | 16 +- include/VBox/dis.h | 9 +- include/VBox/disopcode.h | 2 +- include/VBox/err.h | 206 ++- include/VBox/err.mac | 104 +- include/VBox/err.sed | 2 +- include/VBox/hgcmsvc.h | 2 +- include/VBox/intnet.h | 20 +- include/VBox/intnetinline.h | 63 +- include/VBox/log.h | 545 +++++- include/VBox/nasm.mac | 2 +- include/VBox/ostypes.h | 13 +- include/VBox/param.h | 2 +- include/VBox/pci.h | 45 +- include/VBox/scsi.h | 25 +- include/VBox/settings.h | 213 ++- include/VBox/shflsvc.h | 13 +- include/VBox/sup.h | 31 +- include/VBox/types.h | 7 +- include/VBox/usb.h | 2 +- include/VBox/usbfilter.h | 2 +- include/VBox/usblib-darwin.h | 2 +- include/VBox/usblib-solaris.h | 8 +- include/VBox/usblib-win.h | 2 +- include/VBox/usblib.h | 2 +- include/VBox/various.sed | 7 + include/VBox/vd-cache-plugin.h | 98 +- include/VBox/vd-ifs-internal.h | 261 +-- include/VBox/vd-ifs.h | 41 +- include/VBox/vd-plugin.h | 190 +-- include/VBox/vd.h | 39 +- include/VBox/version.h | 2 +- include/VBox/vmm/cfgm.h | 14 +- include/VBox/vmm/cpum.h | 354 +++- include/VBox/vmm/cpum.mac | 6 +- include/VBox/vmm/cpumctx.h | 12 +- include/VBox/vmm/cpumdis.h | 2 +- include/VBox/vmm/csam.h | 264 +-- include/VBox/vmm/dbgf.h | 423 ++--- include/VBox/vmm/dbgfsel.h | 2 +- include/VBox/vmm/em.h | 151 +- include/VBox/vmm/ftm.h | 19 +- include/VBox/vmm/gmm.h | 2 +- include/VBox/vmm/gvm.h | 2 +- include/VBox/vmm/gvmm.h | 2 +- include/VBox/vmm/hm.h | 265 +++ include/VBox/vmm/hm_svm.h | 811 +++++++++ include/VBox/vmm/hm_vmx.h | 2343 ++++++++++++++++++++++++++ include/VBox/vmm/hm_vmx.mac | 181 ++ include/VBox/vmm/hwacc_svm.h | 744 -------- include/VBox/vmm/hwacc_vmx.h | 1708 ------------------- include/VBox/vmm/hwacc_vmx.mac | 154 -- include/VBox/vmm/hwaccm.h | 154 -- include/VBox/vmm/iem.h | 19 +- include/VBox/vmm/iom.h | 73 +- include/VBox/vmm/mm.h | 7 +- include/VBox/vmm/patm.h | 616 +------ include/VBox/vmm/pdm.h | 3 +- include/VBox/vmm/pdmapi.h | 160 +- include/VBox/vmm/pdmasynccompletion.h | 232 +-- include/VBox/vmm/pdmblkcache.h | 2 +- include/VBox/vmm/pdmcardreaderinfs.h | 91 +- include/VBox/vmm/pdmcommon.h | 4 +- include/VBox/vmm/pdmcritsect.h | 25 +- include/VBox/vmm/pdmcritsectrw.h | 97 ++ include/VBox/vmm/pdmdev.h | 416 +++-- include/VBox/vmm/pdmdrv.h | 52 +- include/VBox/vmm/pdmifs.h | 145 +- include/VBox/vmm/pdmnetinline.h | 2 +- include/VBox/vmm/pdmnetshaper.h | 91 +- include/VBox/vmm/pdmnetshaperint.h | 94 -- include/VBox/vmm/pdmnvram.h | 78 +- include/VBox/vmm/pdmqueue.h | 13 +- include/VBox/vmm/pdmusb.h | 55 +- include/VBox/vmm/pdmwebcaminfs.h | 133 ++ include/VBox/vmm/pgm.h | 39 +- include/VBox/vmm/rem.h | 2 +- include/VBox/vmm/selm.h | 8 +- include/VBox/vmm/ssm.h | 57 +- include/VBox/vmm/stam.h | 48 +- include/VBox/vmm/tm.h | 6 +- include/VBox/vmm/trpm.h | 22 +- include/VBox/vmm/uvm.h | 25 +- include/VBox/vmm/vm.h | 251 +-- include/VBox/vmm/vm.mac | 16 +- include/VBox/vmm/vmapi.h | 233 ++- include/VBox/vmm/vmm.h | 137 +- include/VBox/vrdpusb.h | 2 +- include/VBox/vscsi.h | 44 +- include/VBox/vusb.h | 28 +- include/iprt/aiomgr.h | 155 ++ include/iprt/alloc.h | 2 +- include/iprt/alloca.h | 2 +- include/iprt/asm-amd64-x86.h | 248 ++- include/iprt/asm.h | 178 +- include/iprt/asmdefs.mac | 108 +- include/iprt/assert.h | 123 +- include/iprt/avl.h | 68 +- include/iprt/base64.h | 2 +- include/iprt/buildconfig.h | 2 +- include/iprt/cdefs.h | 384 ++++- include/iprt/cidr.h | 13 +- include/iprt/circbuf.h | 2 +- include/iprt/cpp/list.h | 506 +++--- include/iprt/cpp/ministring.h | 6 +- include/iprt/cpp/mtlist.h | 37 +- include/iprt/cpp/utils.h | 34 + include/iprt/cpp/xml.h | 512 +++++- include/iprt/crc.h | 2 +- include/iprt/critsect.h | 435 ++++- include/iprt/ctype.h | 2 +- include/iprt/dbg.h | 372 +++- include/iprt/dir.h | 59 +- include/iprt/dvm.h | 2 +- include/iprt/env.h | 14 +- include/iprt/err.h | 156 +- include/iprt/err.mac | 71 + include/iprt/err.sed | 2 +- include/iprt/file.h | 92 +- include/iprt/formats/Makefile.kup | 0 include/iprt/formats/codeview.h | 82 + include/iprt/formats/hfs.h | 677 ++++++++ include/iprt/formats/mach-o.h | 626 +++++++ include/iprt/formats/mz.mac | 56 + include/iprt/formats/pe.mac | 722 ++++++++ include/iprt/formats/xar.h | 68 + include/iprt/fs.h | 8 +- include/iprt/getopt.h | 24 +- include/iprt/handletable.h | 13 +- include/iprt/heap.h | 2 +- include/iprt/http.h | 169 ++ include/iprt/initterm.h | 11 +- include/iprt/isofs.h | 2 +- include/iprt/ldr.h | 405 ++++- include/iprt/ldrlazy.h | 102 ++ include/iprt/linux/sysfs.h | 2 +- include/iprt/list.h | 47 +- include/iprt/localipc.h | 8 +- include/iprt/lockvalidator.h | 69 +- include/iprt/log.h | 18 +- include/iprt/mangling.h | 147 +- include/iprt/manifest.h | 40 +- include/iprt/md5.h | 2 +- include/iprt/mem.h | 20 +- include/iprt/memcache.h | 12 +- include/iprt/memobj.h | 2 +- include/iprt/mempool.h | 2 +- include/iprt/memtracker.h | 2 +- include/iprt/message.h | 2 +- include/iprt/mp.h | 24 +- include/iprt/net.h | 77 +- include/iprt/nocrt/amd64/fenv.h | 2 +- include/iprt/nocrt/amd64/math.h | 2 +- include/iprt/nocrt/compiler/compiler.h | 2 +- include/iprt/nocrt/compiler/gcc.h | 2 +- include/iprt/nocrt/compiler/msc.h | 2 +- include/iprt/nocrt/fenv.h | 2 +- include/iprt/nocrt/inttypes.h | 2 +- include/iprt/nocrt/limits.h | 2 +- include/iprt/nocrt/math.h | 2 +- include/iprt/nocrt/setjmp.h | 2 +- include/iprt/nocrt/stdarg.h | 2 +- include/iprt/nocrt/stddef.h | 2 +- include/iprt/nocrt/stdlib.h | 2 +- include/iprt/nocrt/string.h | 2 +- include/iprt/nocrt/x86/fenv.h | 2 +- include/iprt/nocrt/x86/math.h | 2 +- include/iprt/once.h | 86 +- include/iprt/param.h | 2 +- include/iprt/path.h | 500 +++++- include/iprt/pipe.h | 2 +- include/iprt/power.h | 2 +- include/iprt/process.h | 2 +- include/iprt/queueatomic.h | 123 ++ include/iprt/rand.h | 2 +- include/iprt/runtime-loader.h | 6 +- include/iprt/runtime.h | 2 +- include/iprt/s3.h | 2 +- include/iprt/semaphore.h | 2 +- include/iprt/sg.h | 17 +- include/iprt/sha.h | 27 +- include/iprt/sort.h | 2 +- include/iprt/spinlock.h | 4 +- include/iprt/stdint.h | 6 +- include/iprt/strcache.h | 73 +- include/iprt/stream.h | 2 +- include/iprt/string.h | 27 +- include/iprt/symlink.h | 2 +- include/iprt/system.h | 12 +- include/iprt/table.h | 2 +- include/iprt/tar.h | 4 + include/iprt/tcp.h | 34 + include/iprt/test.h | 227 ++- include/iprt/thread.h | 109 +- include/iprt/time.h | 28 +- include/iprt/types.h | 135 +- include/iprt/uni.h | 32 +- include/iprt/uuid.h | 2 +- include/iprt/vfs.h | 28 +- include/iprt/vfslowlevel.h | 2 +- include/iprt/win/lazy-dbghelp.h | 137 ++ include/iprt/x86.h | 402 ++++- include/iprt/x86.mac | 146 +- include/iprt/x86extra.mac | 118 +- include/iprt/zip.h | 51 +- 268 files changed, 19492 insertions(+), 7211 deletions(-) delete mode 100644 include/VBox/DevPCNet.h create mode 100644 include/VBox/RemoteDesktop/VRDEInput.h create mode 100644 include/VBox/RemoteDesktop/VRDEVideoIn.h create mode 100644 include/VBox/VBoxVideoHost3D.h create mode 100644 include/VBox/com/NativeEventQueue.h create mode 100644 include/VBox/vmm/hm.h create mode 100644 include/VBox/vmm/hm_svm.h create mode 100644 include/VBox/vmm/hm_vmx.h create mode 100644 include/VBox/vmm/hm_vmx.mac delete mode 100644 include/VBox/vmm/hwacc_svm.h delete mode 100644 include/VBox/vmm/hwacc_vmx.h delete mode 100644 include/VBox/vmm/hwacc_vmx.mac delete mode 100644 include/VBox/vmm/hwaccm.h create mode 100644 include/VBox/vmm/pdmcritsectrw.h delete mode 100644 include/VBox/vmm/pdmnetshaperint.h create mode 100644 include/VBox/vmm/pdmwebcaminfs.h create mode 100644 include/iprt/aiomgr.h create mode 100644 include/iprt/formats/Makefile.kup create mode 100644 include/iprt/formats/codeview.h create mode 100644 include/iprt/formats/hfs.h create mode 100644 include/iprt/formats/mach-o.h create mode 100644 include/iprt/formats/mz.mac create mode 100644 include/iprt/formats/pe.mac create mode 100644 include/iprt/formats/xar.h create mode 100644 include/iprt/http.h create mode 100644 include/iprt/ldrlazy.h create mode 100644 include/iprt/queueatomic.h create mode 100644 include/iprt/win/lazy-dbghelp.h (limited to 'include') diff --git a/include/Makefile.kmk b/include/Makefile.kmk index 5d5a0ae7..82f278d9 100644 --- a/include/Makefile.kmk +++ b/include/Makefile.kmk @@ -23,8 +23,8 @@ LIBRARIES = SyntaxVBoxIncludeR3 SyntaxVBoxIncludeR0 SyntaxVBoxIncludeRC # Omit headers that are using C++ features and upsets gcc. cpp_features_hdrs := \ - VBox/vmm/hwaccm.h \ - VBox/vmm/hwacc_vmx.h \ + VBox/vmm/hm.h \ + VBox/vmm/hm_vmx.h \ VBox/HostServices/GuestControlSvc.h \ VBox/VBoxCrHgsmi.h \ VBox/VBoxUhgsmi.h diff --git a/include/VBox/DevPCNet.h b/include/VBox/DevPCNet.h deleted file mode 100644 index 52e357ad..00000000 --- a/include/VBox/DevPCNet.h +++ /dev/null @@ -1,99 +0,0 @@ -/** @file - * DevPCNet - Private guest interface for the PCNet device. (DEV) - */ - -/* - * Copyright (C) 2008 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 ___VBox_DevPCNet_h -#define ___VBox_DevPCNet_h - -#include - -/** @defgroup grp_devpcnet AMD PCnet-PCI II / PCnet-FAST III (Am79C970A / Am79C973) Ethernet Controller Emulation. - * { - */ - -#define PCNET_GUEST_INTERFACE_VERSION (1) -#define PCNET_GUEST_SHARED_MEMORY_SIZE _512K -#define PCNET_GUEST_TX_DESCRIPTOR_SIZE 16 -#define PCNET_GUEST_RX_DESCRIPTOR_SIZE 16 -#define PCNET_GUEST_MAX_TX_DESCRIPTORS 128 -#define PCNET_GUEST_MAX_RX_DESCRIPTORS 256 -#define PCNET_GUEST_NIC_BUFFER_SIZE 1536 - -/* 256*16 + 128*16 + 256*1536 + 128*1536 = 582KB */ - -/** - * The header of the PCNet shared memory (VBox specific). - */ -#pragma pack(1) /* paranoia */ -typedef struct -{ - /** The size of the shared memory that's being used. - * (This is <= PCNET_GUEST_SHARED_MEMORY_SIZE.) */ - uint32_t cbUsed; - /** Version (PCNET_GUEST_INTERFACE_VERSION). */ - uint32_t u32Version; - /** Flags (See PCNET_GUEST_FLAGS_*). */ - uint32_t fFlags; - /** Align the following members to 64 bit. */ - uint32_t u32Alignment; - - union - { - struct - { - /** The size (in bytes) of the transmit descriptor array. */ - uint32_t cbTxDescriptors; - /** The size (in bytes) of the receive descriptor array. */ - uint32_t cbRxDescriptors; - /** Offset of the transmit descriptors relative to this header. */ - uint32_t offTxDescriptors; - /** Offset of the receive descriptors relative to this header. */ - uint32_t offRxDescriptors; - /** Offset of the transmit buffers relative to this header. */ - uint32_t offTxBuffers; - /** Offset of the receive buffers relative to this header. */ - uint32_t offRxBuffers; - } V1; - } V; - -} PCNETGUESTSHAREDMEMORY; -#pragma pack() -/** Pointer to the PCNet shared memory header. */ -typedef PCNETGUESTSHAREDMEMORY *PPCNETGUESTSHAREDMEMORY; -/** Const pointer to the PCNet shared memory header. */ -typedef const PCNETGUESTSHAREDMEMORY *PCPCNETGUESTSHAREDMEMORY; - -/** @name fFlags definitions - * @{ - */ -/** Host admits existence private PCNet interface. */ -#define PCNET_GUEST_FLAGS_ADMIT_HOST RT_BIT(0) -/** Guest admits using the private PCNet interface. */ -#define PCNET_GUEST_FLAGS_ADMIT_GUEST RT_BIT(1) -/** @} */ - -/** @} */ - -#endif - diff --git a/include/VBox/ExtPack/ExtPack.h b/include/VBox/ExtPack/ExtPack.h index 4e03b382..c9a6175a 100644 --- a/include/VBox/ExtPack/ExtPack.h +++ b/include/VBox/ExtPack/ExtPack.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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; @@ -149,6 +149,9 @@ typedef struct VBOXEXTPACKHLP */ DECLR3CALLBACKMEMBER(VBOXEXTPACKCTX, pfnGetContext,(PCVBOXEXTPACKHLP pHlp)); + DECLR3CALLBACKMEMBER(int, pfnLoadHGCMService,(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IConsole) *pConsole, + const char *pszServiceLibrary, const char *pszServiceName)); + DECLR3CALLBACKMEMBER(int, pfnReserved1,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved2,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved3,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ @@ -157,13 +160,12 @@ typedef struct VBOXEXTPACKHLP DECLR3CALLBACKMEMBER(int, pfnReserved6,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved7,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved8,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ - DECLR3CALLBACKMEMBER(int, pfnReserved9,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ /** End of structure marker (VBOXEXTPACKHLP_VERSION). */ uint32_t u32EndMarker; } VBOXEXTPACKHLP; /** Current version of the VBOXEXTPACKHLP structure. */ -#define VBOXEXTPACKHLP_VERSION RT_MAKE_U32(0, 1) +#define VBOXEXTPACKHLP_VERSION RT_MAKE_U32(1, 1) /** Pointer to the extension pack callback table. */ diff --git a/include/VBox/HGSMI/HGSMI.h b/include/VBox/HGSMI/HGSMI.h index 352487d9..c34f190c 100644 --- a/include/VBox/HGSMI/HGSMI.h +++ b/include/VBox/HGSMI/HGSMI.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2008 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/include/VBox/HGSMI/HGSMIChSetup.h b/include/VBox/HGSMI/HGSMIChSetup.h index 5f116510..3084a76d 100644 --- a/include/VBox/HGSMI/HGSMIChSetup.h +++ b/include/VBox/HGSMI/HGSMIChSetup.h @@ -3,7 +3,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; @@ -44,9 +44,9 @@ AssertCompileSize(HGSMIBUFFERLOCATION, 8); /* HGSMI setup and configuration data structures. */ /* host->guest commands pending, should be accessed under FIFO lock only */ -#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x1 +#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x1 /* IRQ is fired, should be accessed under VGAState::lock only */ -#define HGSMIHOSTFLAGS_IRQ 0x2 +#define HGSMIHOSTFLAGS_IRQ 0x2 #ifdef VBOX_WITH_WDDM /* one or more guest commands is completed, should be accessed under FIFO lock only */ # define HGSMIHOSTFLAGS_GCOMMAND_COMPLETED 0x4 diff --git a/include/VBox/HGSMI/HGSMIChannels.h b/include/VBox/HGSMI/HGSMIChannels.h index 3b5bd6db..cde3430d 100644 --- a/include/VBox/HGSMI/HGSMIChannels.h +++ b/include/VBox/HGSMI/HGSMIChannels.h @@ -6,7 +6,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/include/VBox/Hardware/VBoxVideoVBE.h b/include/VBox/Hardware/VBoxVideoVBE.h index 405ab3d2..dc61d45d 100644 --- a/include/VBox/Hardware/VBoxVideoVBE.h +++ b/include/VBox/Hardware/VBoxVideoVBE.h @@ -3,7 +3,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; @@ -80,6 +80,7 @@ #define VGA_PORT_HGSMI_HOST 0x3b0 #define VGA_PORT_HGSMI_GUEST 0x3d0 +/* this should be in sync with monitorCount in src/VBox/Main/xml/VirtualBox-settings-common.xsd */ #define VBOX_VIDEO_MAX_SCREENS 64 #endif /* !___VBox_Hardware_VBoxVideoVBE_h */ diff --git a/include/VBox/HostServices/GuestControlSvc.h b/include/VBox/HostServices/GuestControlSvc.h index d7864601..a173fbea 100644 --- a/include/VBox/HostServices/GuestControlSvc.h +++ b/include/VBox/HostServices/GuestControlSvc.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011-2012 Oracle Corporation + * Copyright (C) 2011-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; @@ -41,6 +41,45 @@ namespace guestControl { * Typedefs, constants and inlines * ******************************************************************************/ +#define HGCMSERVICE_NAME "VBoxGuestControlSvc" + +/** Maximum number of concurrent guest sessions a VM can have. */ +#define VBOX_GUESTCTRL_MAX_SESSIONS 32 +/** Maximum number of concurrent guest objects (processes, files, ...) + * a guest session can have. */ +#define VBOX_GUESTCTRL_MAX_OBJECTS _2K +/** Maximum of callback contexts a guest process can have. */ +#define VBOX_GUESTCTRL_MAX_CONTEXTS _64K + +/** Base (start) of guest control session IDs. Session + * ID 0 is reserved for the root process which + * hosts all other guest session processes. */ +#define VBOX_GUESTCTRL_SESSION_ID_BASE 1 + +/** Builds a context ID out of the session ID, object ID and an + * increasing count. */ +#define VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession, uObject, uCount) \ + ( (uint32_t)((uSession) & 0x1f) << 27 \ + | (uint32_t)((uObject) & 0x7ff) << 16 \ + | (uint32_t)((uCount) & 0xffff) \ + ) +/** Creates a context ID out of a session ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSession) \ + ((uint32_t)((uSession) & 0x1f) << 27) +/** Gets the session ID out of a context ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID) \ + (((uContextID) >> 27) & 0x1f) +/** Gets the process ID out of a context ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID) \ + (((uContextID) >> 16) & 0x7ff) +/** Gets the context count of a process out of a context ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID) \ + ((uContextID) & 0xffff) +/** Filter context IDs by session. Can be used in conjunction + * with VbglR3GuestCtrlMsgFilterSet(). */ +#define VBOX_GUESTCTRL_FILTER_BY_SESSION(uSession) \ + (VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSession) | 0xF8000000) + /** * Process status when executed in the guest. */ @@ -75,7 +114,26 @@ enum eProcessStatus #define INPUT_FLAG_EOF RT_BIT(0) /** - * Execution flags. + * Guest session creation flags. + * Only handled internally at the moment. + */ +#define SESSIONCREATIONFLAG_NONE 0x0 + +/** + * Guest directory removement flags. + * Essentially using what IPRT's RTDIRRMREC_F_ + * defines have to offer. + */ +#define DIRREMOVE_FLAG_RECURSIVE RT_BIT(0) +/** Delete the content of the directory and the directory itself. */ +#define DIRREMOVE_FLAG_CONTENT_AND_DIR RT_BIT(1) +/** Only delete the content of the directory, omit the directory it self. */ +#define DIRREMOVE_FLAG_CONTENT_ONLY RT_BIT(2) +/** Mask of valid flags. */ +#define DIRREMOVE_FLAG_VALID_MASK UINT32_C(0x00000003) + +/** + * Guest process creation flags. * Note: Has to match Main's ProcessCreateFlag_* flags! */ #define EXECUTEPROCESSFLAG_NONE 0x0 @@ -95,6 +153,20 @@ enum eProcessStatus #define OUTPUT_HANDLE_ID_STDOUT 1 #define OUTPUT_HANDLE_ID_STDERR 2 +/** + * Guest path rename flags. + * Essentially using what IPRT's RTPATHRENAME_FLAGS_ + * defines have to offer. + */ +/** Do not replace anything. */ +#define PATHRENAME_FLAG_NO_REPLACE UINT32_C(0) +/** This will replace attempt any target which isn't a directory. */ +#define PATHRENAME_FLAG_REPLACE RT_BIT(0) +/** Don't allow symbolic links as part of the path. */ +#define PATHRENAME_FLAG_NO_SYMLINKS RT_BIT(1) +/** Mask of valid flags. */ +#define PATHRENAME_FLAG_VALID_MASK UINT32_C(0x00000002) + /** * Defines for guest process array lengths. */ @@ -103,6 +175,7 @@ enum eProcessStatus #define GUESTPROCESS_MAX_ENV_LEN _64K #define GUESTPROCESS_MAX_USER_LEN 128 #define GUESTPROCESS_MAX_PASSWORD_LEN 128 +#define GUESTPROCESS_MAX_DOMAIN_LEN 256 /** @name Internal tools built into VBoxService which are used in order to * accomplish tasks host<->guest. @@ -134,95 +207,34 @@ enum eInputStatus }; /** - * The guest control callback data header. Must come first - * on each callback structure defined below this struct. + * Structure keeping the context of a host callback. */ -typedef struct VBoxGuestCtrlCallbackHeader +typedef struct VBoxGuestCtrlHostCbCtx { - /** Magic number to identify the structure. */ - uint32_t u32Magic; - /** Context ID to identify callback data. */ - uint32_t u32ContextID; -} CALLBACKHEADER; -typedef CALLBACKHEADER *PCALLBACKHEADER; + /** HGCM Function number. */ + uint32_t uFunction; + /** The context ID. */ + uint32_t uContextID; + /** Protocol version of this guest session. Might + * be 0 if not supported. */ + uint32_t uProtocol; -typedef struct VBoxGuestCtrlCallbackDataClientDisconnected -{ - /** Callback data header. */ - CALLBACKHEADER hdr; -} CALLBACKDATACLIENTDISCONNECTED; -typedef CALLBACKDATACLIENTDISCONNECTED *PCALLBACKDATACLIENTDISCONNECTED; +} VBOXGUESTCTRLHOSTCBCTX, *PVBOXGUESTCTRLHOSTCBCTX; /** - * Data structure to pass to the service extension callback. We use this to - * notify the host of changes to properties. - */ -typedef struct VBoxGuestCtrlCallbackDataExecStatus + * Structure for low level HGCM host callback from + * the guest. No deep copy. */ +typedef struct VBoxGuestCtrlHostCallback { - /** Callback data header. */ - CALLBACKHEADER hdr; - /** The process ID (PID). */ - uint32_t u32PID; - /** The process status. */ - uint32_t u32Status; - /** Optional flags, varies, based on u32Status. */ - uint32_t u32Flags; - /** Optional data buffer (not used atm). */ - void *pvData; - /** Size of optional data buffer (not used atm). */ - uint32_t cbData; -} CALLBACKDATAEXECSTATUS; -typedef CALLBACKDATAEXECSTATUS *PCALLBACKDATAEXECSTATUS; + VBoxGuestCtrlHostCallback(uint32_t cParms, VBOXHGCMSVCPARM paParms[]) + : mParms(cParms), mpaParms(paParms) { } -typedef struct VBoxGuestCtrlCallbackDataExecOut -{ - /** Callback data header. */ - CALLBACKHEADER hdr; - /** The process ID (PID). */ - uint32_t u32PID; - /** The handle ID (stdout/stderr). */ - uint32_t u32HandleId; - /** Optional flags (not used atm). */ - uint32_t u32Flags; - /** Optional data buffer. */ - void *pvData; - /** Size (in bytes) of optional data buffer. */ - uint32_t cbData; -} CALLBACKDATAEXECOUT; -typedef CALLBACKDATAEXECOUT *PCALLBACKDATAEXECOUT; + /** Number of HGCM parameters. */ + uint32_t mParms; + /** Actual HGCM parameters. */ + PVBOXHGCMSVCPARM mpaParms; -typedef struct VBoxGuestCtrlCallbackDataExecInStatus -{ - /** Callback data header. */ - CALLBACKHEADER hdr; - /** The process ID (PID). */ - uint32_t u32PID; - /** Current input status. */ - uint32_t u32Status; - /** Optional flags. */ - uint32_t u32Flags; - /** Size (in bytes) of processed input data. */ - uint32_t cbProcessed; -} CALLBACKDATAEXECINSTATUS; -typedef CALLBACKDATAEXECINSTATUS *PCALLBACKDATAEXECINSTATUS; - -enum eVBoxGuestCtrlCallbackDataMagic -{ - CALLBACKDATAMAGIC_CLIENT_DISCONNECTED = 0x08041984, - - CALLBACKDATAMAGIC_EXEC_STATUS = 0x26011982, - CALLBACKDATAMAGIC_EXEC_OUT = 0x11061949, - CALLBACKDATAMAGIC_EXEC_IN_STATUS = 0x19091951 -}; - -enum eVBoxGuestCtrlCallbackType -{ - VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN = 0, - - VBOXGUESTCTRLCALLBACKTYPE_EXEC_START = 1, - VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT = 2, - VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS = 3 -}; +} VBOXGUESTCTRLHOSTCALLBACK, *PVBOXGUESTCTRLHOSTCALLBACK; /** * The service functions which are callable by host. @@ -233,35 +245,40 @@ enum eHostFn * The host asks the client to cancel all pending waits and exit. */ HOST_CANCEL_PENDING_WAITS = 0, - - /* - * Execution handling. + /** + * The host wants to create a guest session. */ - + HOST_SESSION_CREATE = 20, + /** + * The host wants to close a guest session. + */ + HOST_SESSION_CLOSE = 21, /** * The host wants to execute something in the guest. This can be a command line * or starting a program. + ** Note: Legacy (VBox < 4.3) command. */ HOST_EXEC_CMD = 100, /** * Sends input data for stdin to a running process executed by HOST_EXEC_CMD. + ** Note: Legacy (VBox < 4.3) command. */ HOST_EXEC_SET_INPUT = 101, /** * Gets the current status of a running process, e.g. * new data on stdout/stderr, process terminated etc. + ** Note: Legacy (VBox < 4.3) command. */ HOST_EXEC_GET_OUTPUT = 102, - - /* - * Guest control 2.0 commands start in the 2xx number space. + /** + * Terminates a running guest process. */ - + HOST_EXEC_TERMINATE = 110, /** * Waits for a certain event to happen. This can be an input, output * or status event. */ - HOST_EXEC_WAIT_FOR = 210, + HOST_EXEC_WAIT_FOR = 120, /** * Opens a guest file. */ @@ -273,23 +290,41 @@ enum eHostFn /** * Reads from an opened guest file. */ - HOST_FILE_READ = 242, + HOST_FILE_READ = 250, + /** + * Reads from an opened guest file at + * a specified offset. + */ + HOST_FILE_READ_AT = 251, /** * Write to an opened guest file. */ - HOST_FILE_WRITE = 243, + HOST_FILE_WRITE = 260, + /** + * Write to an opened guest file at + * a specified offset. + */ + HOST_FILE_WRITE_AT = 261, /** * Changes the read & write position of an opened guest file. */ - HOST_FILE_SEEK = 244, + HOST_FILE_SEEK = 270, /** * Gets the current file position of an opened guest file. */ - HOST_FILE_TELL = 245 + HOST_FILE_TELL = 271, + /** + * Removes a directory on the guest. + */ + HOST_DIR_REMOVE = 320, + /** + * Renames a path on the guest. + */ + HOST_PATH_RENAME = 330 }; /** - * The service functions which are called by guest. The numbers may not change, + * The service functions which are called by guest. The numbers may not change, * so we hardcode them. */ enum eGuestFn @@ -298,7 +333,7 @@ enum eGuestFn * Guest waits for a new message the host wants to process on the guest side. * This is a blocking call and can be deferred. */ - GUEST_GET_HOST_MSG = 1, + GUEST_MSG_WAIT = 1, /** * Guest asks the host to cancel all pending waits the guest itself waits on. * This becomes necessary when the guest wants to quit but still waits for @@ -310,30 +345,52 @@ enum eGuestFn * detected when calling service::clientDisconnect(). */ GUEST_DISCONNECTED = 3, - - /* - * Process execution. - * The 1xx commands are legacy guest control commands and - * will be replaced by newer commands in the future. + /** + * Sets a message filter to only get messages which have a certain + * context ID scheme (that is, a specific session, object etc). + * Since VBox 4.3+. */ - + GUEST_MSG_FILTER_SET = 4, + /** + * Unsets (and resets) a previously set message filter. + */ + GUEST_MSG_FILTER_UNSET = 5, + /** + * Skips the current assigned message returned by GUEST_MSG_WAIT. + * Needed for telling the host service to not keep stale + * host commands in the queue. + */ + GUEST_MSG_SKIP = 10, + /** + * General reply to a host message. Only contains basic data + * along with a simple payload. + */ + GUEST_MSG_REPLY = 11, + /** + * General message for updating a pending progress for + * a long task. + */ + GUEST_MSG_PROGRESS_UPDATE = 12, + /** + * Guest reports back a guest session status. + */ + GUEST_SESSION_NOTIFY = 20, + /** + * Guest wants to close a specific guest session. + */ + GUEST_SESSION_CLOSE = 21, /** * Guests sends output from an executed process. */ - GUEST_EXEC_SEND_OUTPUT = 100, + GUEST_EXEC_OUTPUT = 100, /** * Guest sends a status update of an executed process to the host. */ - GUEST_EXEC_SEND_STATUS = 101, + GUEST_EXEC_STATUS = 101, /** * Guests sends an input status notification to the host. */ - GUEST_EXEC_SEND_INPUT_STATUS = 102, - - /* - * Guest control 2.0 commands start in the 2xx number space. - */ - + GUEST_EXEC_INPUT_STATUS = 102, /** * Guest notifies the host about some I/O event. This can be * a stdout, stderr or a stdin event. The actual event only tells @@ -341,24 +398,87 @@ enum eGuestFn * transmitting the data. */ GUEST_EXEC_IO_NOTIFY = 210, - /** Guest notifies the host about a file event, like opening, - * closing, seeking etc. + /** + * Guest notifies the host about some directory event. + */ + GUEST_DIR_NOTIFY = 230, + /** + * Guest notifies the host about some file event. */ GUEST_FILE_NOTIFY = 240 }; +/** + * Guest session notification types. + * @sa HGCMMsgSessionNotify. + */ +enum GUEST_SESSION_NOTIFYTYPE +{ + GUEST_SESSION_NOTIFYTYPE_UNDEFINED = 0, + /** Something went wrong (see rc). */ + GUEST_SESSION_NOTIFYTYPE_ERROR = 1, + /** Guest session has been started. */ + GUEST_SESSION_NOTIFYTYPE_STARTED = 11, + /** Guest session terminated normally. */ + GUEST_SESSION_NOTIFYTYPE_TEN = 20, + /** Guest session terminated via signal. */ + GUEST_SESSION_NOTIFYTYPE_TES = 30, + /** Guest session terminated abnormally. */ + GUEST_SESSION_NOTIFYTYPE_TEA = 40, + /** Guest session timed out and was killed. */ + GUEST_SESSION_NOTIFYTYPE_TOK = 50, + /** Guest session timed out and was not killed successfully. */ + GUEST_SESSION_NOTIFYTYPE_TOA = 60, + /** Service/OS is stopping, process was killed. */ + GUEST_SESSION_NOTIFYTYPE_DWN = 150 +}; + +/** + * Guest directory notification types. + * @sa HGCMMsgDirNotify. + */ +enum GUEST_DIR_NOTIFYTYPE +{ + GUEST_DIR_NOTIFYTYPE_UNKNOWN = 0, + /** Something went wrong (see rc). */ + GUEST_DIR_NOTIFYTYPE_ERROR = 1, + /** Guest directory opened. */ + GUEST_DIR_NOTIFYTYPE_OPEN = 10, + /** Guest directory closed. */ + GUEST_DIR_NOTIFYTYPE_CLOSE = 20, + /** Information about an open guest directory. */ + GUEST_DIR_NOTIFYTYPE_INFO = 40, + /** Guest directory created. */ + GUEST_DIR_NOTIFYTYPE_CREATE = 70, + /** Guest directory deleted. */ + GUEST_DIR_NOTIFYTYPE_REMOVE = 80 +}; + /** * Guest file notification types. + * @sa HGCMMsgFileNotify. */ -enum eGuestFileNotifyType +enum GUEST_FILE_NOTIFYTYPE { - GUESTFILENOTIFYTYPE_ERROR = 0, - GUESTFILENOTIFYTYPE_OPEN = 10, - GUESTFILENOTIFYTYPE_CLOSE = 20, - GUESTFILENOTIFYTYPE_READ = 30, - GUESTFILENOTIFYTYPE_WRITE = 40, - GUESTFILENOTIFYTYPE_SEEK = 50, - GUESTFILENOTIFYTYPE_TELL = 60 + GUEST_FILE_NOTIFYTYPE_UNKNOWN = 0, + GUEST_FILE_NOTIFYTYPE_ERROR = 1, + GUEST_FILE_NOTIFYTYPE_OPEN = 10, + GUEST_FILE_NOTIFYTYPE_CLOSE = 20, + GUEST_FILE_NOTIFYTYPE_READ = 30, + GUEST_FILE_NOTIFYTYPE_WRITE = 40, + GUEST_FILE_NOTIFYTYPE_SEEK = 50, + GUEST_FILE_NOTIFYTYPE_TELL = 60 +}; + +/** + * Guest file seeking types. Has to + * match FileSeekType in Main. + */ +enum GUEST_FILE_SEEKTYPE +{ + GUEST_FILE_SEEKTYPE_BEGIN = 1, + GUEST_FILE_SEEKTYPE_CURRENT = 4, + GUEST_FILE_SEEKTYPE_END = 8 }; /* @@ -366,10 +486,14 @@ enum eGuestFileNotifyType */ #pragma pack (1) -typedef struct VBoxGuestCtrlHGCMMsgType +/** + * Waits for a host command to arrive. The structure then contains the + * actual message type + required number of parameters needed to successfully + * retrieve that host command (in a next round). + */ +typedef struct HGCMMsgCmdWaitFor { VBoxGuestHGCMCallInfo hdr; - /** * The returned command the host wants to * run on the guest. @@ -377,22 +501,137 @@ typedef struct VBoxGuestCtrlHGCMMsgType HGCMFunctionParameter msg; /* OUT uint32_t */ /** Number of parameters the message needs. */ HGCMFunctionParameter num_parms; /* OUT uint32_t */ +} HGCMMsgCmdWaitFor; + +/** + * Asks the guest control host service to set a command + * filter for this client. This filter will then only + * deliver messages to the client which match the + * wanted context ID (ranges). + */ +typedef struct HGCMMsgCmdFilterSet +{ + VBoxGuestHGCMCallInfo hdr; + /** Value to filter for after filter mask + * was applied. */ + HGCMFunctionParameter value; /* IN uint32_t */ + /** Mask to add to the current set filter. */ + HGCMFunctionParameter mask_add; /* IN uint32_t */ + /** Mask to remove from the current set filter. */ + HGCMFunctionParameter mask_remove; /* IN uint32_t */ + /** Filter flags; currently unused. */ + HGCMFunctionParameter flags; /* IN uint32_t */ +} HGCMMsgCmdFilterSet; -} VBoxGuestCtrlHGCMMsgType; +/** + * Asks the guest control host service to disable + * a previously set message filter again. + */ +typedef struct HGCMMsgCmdFilterUnset +{ + VBoxGuestHGCMCallInfo hdr; + /** Unset flags; currently unused. */ + HGCMFunctionParameter flags; /* IN uint32_t */ +} HGCMMsgCmdFilterUnset; + +/** + * Asks the guest control host service to skip the + * currently assigned host command returned by + * VbglR3GuestCtrlMsgWaitFor(). + */ +typedef struct HGCMMsgCmdSkip +{ + VBoxGuestHGCMCallInfo hdr; + /** Skip flags; currently unused. */ + HGCMFunctionParameter flags; /* IN uint32_t */ +} HGCMMsgCmdSkip; /** * Asks the guest control host service to cancel all pending (outstanding) - * waits which were not processed yet. This is handy for a graceful shutdown. + * waits which were not processed yet. This is handy for a graceful shutdown. + */ +typedef struct HGCMMsgCancelPendingWaits +{ + VBoxGuestHGCMCallInfo hdr; +} HGCMMsgCancelPendingWaits; + +typedef struct HGCMMsgCmdReply +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Message type. */ + HGCMFunctionParameter type; + /** IPRT result of overall operation. */ + HGCMFunctionParameter rc; + /** Optional payload to this reply. */ + HGCMFunctionParameter payload; +} HGCMMsgCmdReply; + +/** + * Creates a guest session. + */ +typedef struct HGCMMsgSessionOpen +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** The guest control protocol version this + * session is about to use. */ + HGCMFunctionParameter protocol; + /** The user name to run the guest session under. */ + HGCMFunctionParameter username; + /** The user's password. */ + HGCMFunctionParameter password; + /** The domain to run the guest session under. */ + HGCMFunctionParameter domain; + /** Session creation flags. */ + HGCMFunctionParameter flags; +} HGCMMsgSessionOpen; + +/** + * Terminates (closes) a guest session. + */ +typedef struct HGCMMsgSessionClose +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Session termination flags. */ + HGCMFunctionParameter flags; +} HGCMMsgSessionClose; + +/** + * Reports back a guest session's status. */ -typedef struct VBoxGuestCtrlHGCMMsgCancelPendingWaits +typedef struct HGCMMsgSessionNotify +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Notification type. */ + HGCMFunctionParameter type; + /** Notification result. */ + HGCMFunctionParameter result; +} HGCMMsgSessionNotify; + +typedef struct HGCMMsgPathRename { VBoxGuestHGCMCallInfo hdr; -} VBoxGuestCtrlHGCMMsgCancelPendingWaits; + /** UInt32: Context ID. */ + HGCMFunctionParameter context; + /** Source to rename. */ + HGCMFunctionParameter source; + /** Destination to rename source to. */ + HGCMFunctionParameter dest; + /** UInt32: Rename flags. */ + HGCMFunctionParameter flags; +} HGCMMsgPathRename; /** * Executes a command inside the guest. */ -typedef struct VBoxGuestCtrlHGCMMsgExecCmd +typedef struct HGCMMsgProcExec { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -411,22 +650,43 @@ typedef struct VBoxGuestCtrlHGCMMsgExecCmd HGCMFunctionParameter cb_env; /** The actual environment block. */ HGCMFunctionParameter env; - /** The user name to run the executed command under. */ - HGCMFunctionParameter username; - /** The user's password. */ - HGCMFunctionParameter password; - /** Timeout (in msec) which either specifies the - * overall lifetime of the process or how long it - * can take to bring the process up and running - - * (depends on the IGuest::ProcessCreateFlag_*). */ - HGCMFunctionParameter timeout; - -} VBoxGuestCtrlHGCMMsgExecCmd; + union + { + struct + { + /** The user name to run the executed command under. + * Only for VBox < 4.3 hosts. */ + HGCMFunctionParameter username; + /** The user's password. + * Only for VBox < 4.3 hosts. */ + HGCMFunctionParameter password; + /** Timeout (in msec) which either specifies the + * overall lifetime of the process or how long it + * can take to bring the process up and running - + * (depends on the IGuest::ProcessCreateFlag_*). */ + HGCMFunctionParameter timeout; + } v1; + struct + { + /** Timeout (in ms) which either specifies the + * overall lifetime of the process or how long it + * can take to bring the process up and running - + * (depends on the IGuest::ProcessCreateFlag_*). */ + HGCMFunctionParameter timeout; + /** Process priority. */ + HGCMFunctionParameter priority; + /** Number of process affinity blocks. */ + HGCMFunctionParameter num_affinity; + /** Pointer to process affinity blocks (uint64_t). */ + HGCMFunctionParameter affinity; + } v2; + } u; +} HGCMMsgProcExec; /** - * Injects input to a previously executed process via stdin. + * Sends input to a guest process via stdin. */ -typedef struct VBoxGuestCtrlHGCMMsgExecIn +typedef struct HGCMMsgProcInput { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -439,14 +699,13 @@ typedef struct VBoxGuestCtrlHGCMMsgExecIn HGCMFunctionParameter data; /** Actual size of data (in bytes). */ HGCMFunctionParameter size; - -} VBoxGuestCtrlHGCMMsgExecIn; +} HGCMMsgProcInput; /** * Retrieves ouptut from a previously executed process * from stdout/stderr. */ -typedef struct VBoxGuestCtrlHGCMMsgExecOut +typedef struct HGCMMsgProcOutput { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -459,14 +718,12 @@ typedef struct VBoxGuestCtrlHGCMMsgExecOut HGCMFunctionParameter flags; /** Data buffer. */ HGCMFunctionParameter data; - -} VBoxGuestCtrlHGCMMsgExecOut; +} HGCMMsgProcOutput; /** - * Reports the current status of a (just) started - * or terminated process. + * Reports the current status of a guest process. */ -typedef struct VBoxGuestCtrlHGCMMsgExecStatus +typedef struct HGCMMsgProcStatus { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -479,13 +736,12 @@ typedef struct VBoxGuestCtrlHGCMMsgExecStatus HGCMFunctionParameter flags; /** Optional data buffer (not used atm). */ HGCMFunctionParameter data; - -} VBoxGuestCtrlHGCMMsgExecStatus; +} HGCMMsgProcStatus; /** * Reports back the status of data written to a process. */ -typedef struct VBoxGuestCtrlHGCMMsgExecStatusIn +typedef struct HGCMMsgProcStatusInput { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -498,81 +754,119 @@ typedef struct VBoxGuestCtrlHGCMMsgExecStatusIn HGCMFunctionParameter flags; /** Data written. */ HGCMFunctionParameter written; - -} VBoxGuestCtrlHGCMMsgExecStatusIn; +} HGCMMsgProcStatusInput; /* * Guest control 2.0 messages. */ /** - * Reports back the currente I/O status of a guest process. + * Terminates a guest process. */ -typedef struct VBoxGuestCtrlHGCMMsgExecIONotify +typedef struct HGCMMsgProcTerminate { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; - /** Data written. */ - HGCMFunctionParameter written; + /** The process ID (PID). */ + HGCMFunctionParameter pid; +} HGCMMsgProcTerminate; -} VBoxGuestCtrlHGCMMsgExecIONotify; +/** + * Waits for certain events to happen. + */ +typedef struct HGCMMsgProcWaitFor +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** The process ID (PID). */ + HGCMFunctionParameter pid; + /** Wait (event) flags. */ + HGCMFunctionParameter flags; + /** Timeout (in ms). */ + HGCMFunctionParameter timeout; +} HGCMMsgProcWaitFor; + +typedef struct HGCMMsgDirRemove +{ + VBoxGuestHGCMCallInfo hdr; + /** UInt32: Context ID. */ + HGCMFunctionParameter context; + /** Directory to remove. */ + HGCMFunctionParameter path; + /** UInt32: Removement flags. */ + HGCMFunctionParameter flags; +} HGCMMsgDirRemove; /** * Opens a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileOpen +typedef struct HGCMMsgFileOpen { VBoxGuestHGCMCallInfo hdr; - /** Context ID. */ + /** UInt32: Context ID. */ HGCMFunctionParameter context; /** File to open. */ HGCMFunctionParameter filename; /** Open mode. */ HGCMFunctionParameter openmode; - /** Disposition. */ + /** Disposition mode. */ HGCMFunctionParameter disposition; - /** Creation mode. */ + /** Sharing mode. */ + HGCMFunctionParameter sharing; + /** UInt32: Creation mode. */ HGCMFunctionParameter creationmode; - /** Offset. */ + /** UInt64: Initial offset. */ HGCMFunctionParameter offset; - -} VBoxGuestCtrlHGCMMsgFileOpen; +} HGCMMsgFileOpen; /** * Closes a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileClose +typedef struct HGCMMsgFileClose { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; /** File handle to close. */ HGCMFunctionParameter handle; - -} VBoxGuestCtrlHGCMMsgFileClose; +} HGCMMsgFileClose; /** * Reads from a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileRead +typedef struct HGCMMsgFileRead { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; /** File handle to read from. */ HGCMFunctionParameter handle; - /** Actual size of data (in bytes). */ + /** Size (in bytes) to read. */ HGCMFunctionParameter size; - /** Where to put the read data into. */ - HGCMFunctionParameter data; +} HGCMMsgFileRead; -} VBoxGuestCtrlHGCMMsgFileRead; +/** + * Reads at a specified offset from a guest file. + */ +typedef struct HGCMMsgFileReadAt +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** File handle to read from. */ + HGCMFunctionParameter handle; + /** Offset where to start reading from. */ + HGCMFunctionParameter offset; + /** Actual size of data (in bytes). */ + HGCMFunctionParameter size; +} HGCMMsgFileReadAt; /** * Writes to a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileWrite +typedef struct HGCMMsgFileWrite { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -583,13 +877,30 @@ typedef struct VBoxGuestCtrlHGCMMsgFileWrite HGCMFunctionParameter size; /** Data buffer to write to the file. */ HGCMFunctionParameter data; +} HGCMMsgFileWrite; -} VBoxGuestCtrlHGCMMsgFileWrite; +/** + * Writes at a specified offset to a guest file. + */ +typedef struct HGCMMsgFileWriteAt +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** File handle to write to. */ + HGCMFunctionParameter handle; + /** Offset where to start reading from. */ + HGCMFunctionParameter offset; + /** Actual size of data (in bytes). */ + HGCMFunctionParameter size; + /** Data buffer to write to the file. */ + HGCMFunctionParameter data; +} HGCMMsgFileWriteAt; /** * Seeks the read/write position of a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileSeek +typedef struct HGCMMsgFileSeek { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -600,48 +911,276 @@ typedef struct VBoxGuestCtrlHGCMMsgFileSeek HGCMFunctionParameter method; /** The seeking offset. */ HGCMFunctionParameter offset; - -} VBoxGuestCtrlHGCMMsgFileSeek; +} HGCMMsgFileSeek; /** * Tells the current read/write position of a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileTell +typedef struct HGCMMsgFileTell { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; /** File handle to get the current position for. */ HGCMFunctionParameter handle; +} HGCMMsgFileTell; -} VBoxGuestCtrlHGCMMsgFileTell; +/****************************************************************************** +* HGCM replies from the guest. These are handled in Main's low-level HGCM * +* callbacks and dispatched to the appropriate guest object. * +******************************************************************************/ -typedef struct VBoxGuestCtrlHGCMMsgFileNotify +typedef struct HGCMReplyFileNotify { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; - /** The file handle. */ - HGCMFunctionParameter handle; /** Notification type. */ HGCMFunctionParameter type; - /** Notification payload. */ - HGCMFunctionParameter payload; - -} VBoxGuestCtrlHGCMMsgFileNotify; + /** IPRT result of overall operation. */ + HGCMFunctionParameter rc; + union + { + struct + { + /** Guest file handle. */ + HGCMFunctionParameter handle; + } open; + /** Note: Close does not have any additional data (yet). */ + struct + { + /** Actual data read (if any). */ + HGCMFunctionParameter data; + } read; + struct + { + /** How much data (in bytes) have been successfully written. */ + HGCMFunctionParameter written; + } write; + struct + { + HGCMFunctionParameter offset; + } seek; + struct + { + HGCMFunctionParameter offset; + } tell; + } u; +} HGCMReplyFileNotify; + +typedef struct HGCMReplyDirNotify +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Notification type. */ + HGCMFunctionParameter type; + /** IPRT result of overall operation. */ + HGCMFunctionParameter rc; + union + { + struct + { + /** Directory information. */ + HGCMFunctionParameter objInfo; + } info; + struct + { + /** Guest directory handle. */ + HGCMFunctionParameter handle; + } open; + struct + { + /** Current read directory entry. */ + HGCMFunctionParameter entry; + /** Extended entry object information. Optional. */ + HGCMFunctionParameter objInfo; + } read; + } u; +} HGCMReplyDirNotify; #pragma pack () +/****************************************************************************** +* Callback data structures. * +******************************************************************************/ + +/** + * The guest control callback data header. Must come first + * on each callback structure defined below this struct. + */ +typedef struct CALLBACKDATA_HEADER +{ + /** Context ID to identify callback data. This is + * and *must* be the very first parameter in this + * structure to still be backwards compatible. */ + uint32_t uContextID; +} CALLBACKDATA_HEADER, *PCALLBACKDATA_HEADER; + +/* + * These structures make up the actual low level HGCM callback data sent from + * the guest back to the host. + */ + +typedef struct CALLBACKDATA_CLIENT_DISCONNECTED +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; +} CALLBACKDATA_CLIENT_DISCONNECTED, *PCALLBACKDATA_CLIENT_DISCONNECTED; + +typedef struct CALLBACKDATA_MSG_REPLY +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** Notification result. Note: int vs. uint32! */ + uint32_t rc; + /** Pointer to optional payload. */ + void *pvPayload; + /** Payload size (in bytes). */ + uint32_t cbPayload; +} CALLBACKDATA_MSG_REPLY, *PCALLBACKDATA_MSG_REPLY; + +typedef struct CALLBACKDATA_SESSION_NOTIFY +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** Notification result. Note: int vs. uint32! */ + uint32_t uResult; +} CALLBACKDATA_SESSION_NOTIFY, *PCALLBACKDATA_SESSION_NOTIFY; + +typedef struct CALLBACKDATA_PROC_STATUS +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** The process ID (PID). */ + uint32_t uPID; + /** The process status. */ + uint32_t uStatus; + /** Optional flags, varies, based on u32Status. */ + uint32_t uFlags; + /** Optional data buffer (not used atm). */ + void *pvData; + /** Size of optional data buffer (not used atm). */ + uint32_t cbData; +} CALLBACKDATA_PROC_STATUS, *PCALLBACKDATA_PROC_STATUS; + +typedef struct CALLBACKDATA_PROC_OUTPUT +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** The process ID (PID). */ + uint32_t uPID; + /** The handle ID (stdout/stderr). */ + uint32_t uHandle; + /** Optional flags (not used atm). */ + uint32_t uFlags; + /** Optional data buffer. */ + void *pvData; + /** Size (in bytes) of optional data buffer. */ + uint32_t cbData; +} CALLBACKDATA_PROC_OUTPUT, *PCALLBACKDATA_PROC_OUTPUT; + +typedef struct CALLBACKDATA_PROC_INPUT +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** The process ID (PID). */ + uint32_t uPID; + /** Current input status. */ + uint32_t uStatus; + /** Optional flags. */ + uint32_t uFlags; + /** Size (in bytes) of processed input data. */ + uint32_t uProcessed; +} CALLBACKDATA_PROC_INPUT, *PCALLBACKDATA_PROC_INPUT; + /** - * Structure for buffering execution requests in the host service. + * General guest directory notification callback. */ -typedef struct VBoxGuestCtrlParamBuffer +typedef struct CALLBACKDATA_DIR_NOTIFY { - uint32_t uMsg; - uint32_t uParmCount; - PVBOXHGCMSVCPARM pParms; -} VBOXGUESTCTRPARAMBUFFER; -typedef VBOXGUESTCTRPARAMBUFFER *PVBOXGUESTCTRPARAMBUFFER; + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** IPRT result of overall operation. */ + uint32_t rc; + union + { + struct + { + /** Size (in bytes) of directory information. */ + uint32_t cbObjInfo; + /** Pointer to directory information. */ + void *pvObjInfo; + } info; + struct + { + /** Guest directory handle. */ + uint32_t uHandle; + } open; + /** Note: Close does not have any additional data (yet). */ + struct + { + /** Size (in bytes) of directory entry information. */ + uint32_t cbEntry; + /** Pointer to directory entry information. */ + void *pvEntry; + /** Size (in bytes) of directory entry object information. */ + uint32_t cbObjInfo; + /** Pointer to directory entry object information. */ + void *pvObjInfo; + } read; + } u; +} CALLBACKDATA_DIR_NOTIFY, *PCALLBACKDATA_DIR_NOTIFY; + +/** + * General guest file notification callback. + */ +typedef struct CALLBACKDATA_FILE_NOTIFY +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** IPRT result of overall operation. */ + uint32_t rc; + union + { + struct + { + /** Guest file handle. */ + uint32_t uHandle; + } open; + /** Note: Close does not have any additional data (yet). */ + struct + { + /** How much data (in bytes) have been read. */ + uint32_t cbData; + /** Actual data read (if any). */ + void *pvData; + } read; + struct + { + /** How much data (in bytes) have been successfully written. */ + uint32_t cbWritten; + } write; + struct + { + /** New file offset after successful seek. */ + uint64_t uOffActual; + } seek; + struct + { + /** New file offset after successful tell. */ + uint64_t uOffActual; + } tell; + } u; +} CALLBACKDATA_FILE_NOTIFY, *PCALLBACKDATA_FILE_NOTIFY; } /* namespace guestControl */ diff --git a/include/VBox/HostServices/GuestPropertySvc.h b/include/VBox/HostServices/GuestPropertySvc.h index 7e99d2ec..baa54c82 100644 --- a/include/VBox/HostServices/GuestPropertySvc.h +++ b/include/VBox/HostServices/GuestPropertySvc.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/include/VBox/HostServices/Service.h b/include/VBox/HostServices/Service.h index 98e227a2..b82a04f9 100644 --- a/include/VBox/HostServices/Service.h +++ b/include/VBox/HostServices/Service.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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/include/VBox/HostServices/VBoxClipboardExt.h b/include/VBox/HostServices/VBoxClipboardExt.h index a1392ec0..b9d52dbb 100644 --- a/include/VBox/HostServices/VBoxClipboardExt.h +++ b/include/VBox/HostServices/VBoxClipboardExt.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/include/VBox/HostServices/VBoxClipboardSvc.h b/include/VBox/HostServices/VBoxClipboardSvc.h index 0bb5607c..d8240e60 100644 --- a/include/VBox/HostServices/VBoxClipboardSvc.h +++ b/include/VBox/HostServices/VBoxClipboardSvc.h @@ -1,10 +1,9 @@ /** @file - * Shared Clipboard: - * Common header for host service and guest clients. + * Shared Clipboard - Common header for host service and guest clients. */ /* - * 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; @@ -43,9 +42,9 @@ /* * Supported data formats. Bit mask. */ -#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT 0x01 -#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP 0x02 -#define VBOX_SHARED_CLIPBOARD_FMT_HTML 0x04 +#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT UINT32_C(0x01) +#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP UINT32_C(0x02) +#define VBOX_SHARED_CLIPBOARD_FMT_HTML UINT32_C(0x04) /* * The service functions which are callable by host. diff --git a/include/VBox/HostServices/VBoxCrOpenGLSvc.h b/include/VBox/HostServices/VBoxCrOpenGLSvc.h index 150faac7..e09f9a2f 100644 --- a/include/VBox/HostServices/VBoxCrOpenGLSvc.h +++ b/include/VBox/HostServices/VBoxCrOpenGLSvc.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; @@ -31,6 +31,8 @@ #include #include #include +#include +#include /* crOpenGL host functions */ #define SHCRGL_HOST_FN_SET_CONSOLE (1) @@ -43,6 +45,11 @@ #endif #define SHCRGL_HOST_FN_VIEWPORT_CHANGED (15) #define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20) +#define SHCRGL_HOST_FN_DEV_RESIZE (22) +#define SHCRGL_HOST_FN_VIEWPORT_CHANGED2 (23) +#define SHCRGL_HOST_FN_TAKE_SCREENSHOT (24) +#define SHCRGL_HOST_FN_WINDOWS_SHOW (25) +#define SHCRGL_HOST_FN_CTL (26) /* crOpenGL guest functions */ #define SHCRGL_GUEST_FN_WRITE (2) #define SHCRGL_GUEST_FN_READ (3) @@ -52,22 +59,27 @@ #define SHCRGL_GUEST_FN_SET_PID (12) #define SHCRGL_GUEST_FN_WRITE_BUFFER (13) #define SHCRGL_GUEST_FN_WRITE_READ_BUFFERED (14) +#define SHCRGL_GUEST_FN_GET_CAPS (15) /* Parameters count */ #define SHCRGL_CPARMS_SET_CONSOLE (1) #define SHCRGL_CPARMS_SET_VM (1) -#define SHCRGL_CPARMS_SET_VISIBLE_REGION (2) +#define SHCRGL_CPARMS_SET_VISIBLE_REGION (1) #define SHCRGL_CPARMS_WRITE (1) #define SHCRGL_CPARMS_READ (2) #define SHCRGL_CPARMS_WRITE_READ (3) #define SHCRGL_CPARMS_SET_VERSION (2) #define SHCRGL_CPARMS_SCREEN_CHANGED (1) +#define SHCRGL_CPARMS_DEV_RESIZE (1) #define SHCRGL_CPARMS_INJECT (2) #define SHCRGL_CPARMS_SET_PID (1) #define SHCRGL_CPARMS_WRITE_BUFFER (4) #define SHCRGL_CPARMS_WRITE_READ_BUFFERED (3) #define SHCRGL_CPARMS_SET_OUTPUT_REDIRECT (1) +#define SHCRGL_CPARMS_CRCMD_NOTIFY_CMDS (0) #define SHCRGL_CPARMS_VIEWPORT_CHANGED (5) +#define SHCRGL_CPARMS_VIEWPORT_CHANGED2 (1) +#define SHCRGL_CPARMS_GET_CAPS (1) /* @todo Move to H3DOR.h begin */ @@ -89,7 +101,7 @@ typedef struct { int32_t x, int32_t y, uint32_t w, uint32_t h)); /* Update the window visible region. */ DECLR3CALLBACKMEMBER(void, H3DORVisibleRegion, (void *pvInstance, - uint32_t cRects, RTRECT *paRects)); + uint32_t cRects, const RTRECT *paRects)); /* A rendered 3D frame is ready. Format of pvData is "pszFormat" parameter of H3DORBegin. */ DECLR3CALLBACKMEMBER(void, H3DORFrame, (void *pvInstance, void *pvData, uint32_t cbData)); @@ -268,6 +280,17 @@ typedef struct } CRVBOXHGCMSETVERSION; +/** GUEST_FN_GET_CAPS Parameters structure. */ +typedef struct +{ + VBoxGuestHGCMCallInfo hdr; + + /** 32bit, out + * Caps + */ + HGCMFunctionParameter Caps; +} CRVBOXHGCMGETCAPS; + /** GUEST_FN_INJECT Parameters structure. */ typedef struct { @@ -343,4 +366,44 @@ typedef struct } CRVBOXHGCMWRITEREADBUFFERED; + +typedef struct +{ + VBVAINFOSCREEN Screen; + void *pvVRAM; +} CRVBOXHGCMDEVRESIZE; + +typedef struct +{ + uint32_t u32Screen; + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +} CRVBOXHGCMVIEWPORT; + +typedef DECLCALLBACKPTR(void, PFNCRSCREENSHOTREPORT)(void *pvCtx, uint32_t uScreen, + uint32_t x, uint32_t y, uint32_t uBitsPerPixel, + uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight, + uint8_t *pu8BufferAddress, uint64_t u64TimeStamp); + +typedef DECLCALLBACKPTR(bool, PFNCRSCREENSHOTBEGIN)(void *pvCtx, uint32_t uScreen, uint64_t u64TimeStamp); +typedef DECLCALLBACKPTR(void, PFNCRSCREENSHOTEND)(void *pvCtx, uint32_t uScreen, uint64_t u64TimeStamp); + +#define CRSCREEN_ALL (0xffffffff) + +typedef struct +{ + /* screen id or CRSCREEN_ALL to specify all enabled */ + uint32_t u32Screen; + uint32_t u32Width; + uint32_t u32Height; + uint32_t u32Pitch; + void *pvBuffer; + void *pvContext; + PFNCRSCREENSHOTBEGIN pfnScreenshotBegin; + PFNCRSCREENSHOTREPORT pfnScreenshotPerform; + PFNCRSCREENSHOTEND pfnScreenshotEnd; +} CRVBOXHGCMTAKESCREENSHOT; + #endif diff --git a/include/VBox/HostServices/VBoxHostChannel.h b/include/VBox/HostServices/VBoxHostChannel.h index e3c30337..bf3c1434 100644 --- a/include/VBox/HostServices/VBoxHostChannel.h +++ b/include/VBox/HostServices/VBoxHostChannel.h @@ -1,5 +1,5 @@ /** @file - * + * * Host Channel: the service definition. */ @@ -168,6 +168,13 @@ typedef struct VBOXHOSTCHANNELCALLBACKS */ DECLR3CALLBACKMEMBER(void, HostChannelCallbackEvent, (void *pvCallbacks, void *pvChannel, uint32_t u32Id, const void *pvEvent, uint32_t cbEvent)); + + /* The channel has been deleted by the provider. pvCallback will not be used anymore. + * + * @param pvCallbacks The callback context specified in HostChannelAttach. + * @param pvChannel The channel instance returned by HostChannelAttach. + */ + DECLR3CALLBACKMEMBER(void, HostChannelCallbackDeleted, (void *pvCallbacks, void *pvChannel)); } VBOXHOSTCHANNELCALLBACKS; typedef struct VBOXHOSTCHANNELINTERFACE diff --git a/include/VBox/HostServices/VBoxOGLOp.h b/include/VBox/HostServices/VBoxOGLOp.h index d125c254..02c80289 100644 --- a/include/VBox/HostServices/VBoxOGLOp.h +++ b/include/VBox/HostServices/VBoxOGLOp.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/include/VBox/RemoteDesktop/VRDE.h b/include/VBox/RemoteDesktop/VRDE.h index d8a4946d..ba129862 100644 --- a/include/VBox/RemoteDesktop/VRDE.h +++ b/include/VBox/RemoteDesktop/VRDE.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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; @@ -1135,11 +1135,9 @@ typedef struct _VRDEENTRYPOINTS_3 * which tells the server to bind to either of ports: * 3000, 3010, 3011, 3012, 4000. */ -#ifdef VBOX_WITH_VRDP_VIDEO_CHANNEL #define VRDE_QP_VIDEO_CHANNEL (5) #define VRDE_QP_VIDEO_CHANNEL_QUALITY (6) #define VRDE_QP_VIDEO_CHANNEL_SUNFLSH (7) -#endif /* VBOX_WITH_VRDP_VIDEO_CHANNEL */ #define VRDE_QP_FEATURE (8) /* VRDEFEATURE structure. Generic interface to query named VRDE properties. */ #define VRDE_SP_BASE 0x1000 diff --git a/include/VBox/RemoteDesktop/VRDEImage.h b/include/VBox/RemoteDesktop/VRDEImage.h index 929b08ba..951852db 100644 --- a/include/VBox/RemoteDesktop/VRDEImage.h +++ b/include/VBox/RemoteDesktop/VRDEImage.h @@ -208,16 +208,19 @@ typedef struct VRDEIMAGEINTERFACE /* * Notifications. - * u32Id paramater of VRDEIMAGECALLBACKS::VRDEImageCbNotify. + * u32Id parameter of VRDEIMAGECALLBACKS::VRDEImageCbNotify. */ -#define VRDE_IMAGE_NOTIFY_HANDLE_CREATE 1 /* Result of an image handle create request. */ +#define VRDE_IMAGE_NOTIFY_HANDLE_CREATE 1 /* Async result of VRDEImageHandleCreate. + * pvData: uint32_t = 0 if stream was not created, + * a non zero value otherwise. + */ typedef struct VRDEIMAGECALLBACKS { /** The header. */ VRDEINTERFACEHDR header; - /** Generic notification callback. Reserved for future use. + /** Generic notification callback. * * @param hServer The server instance handle. * @param pvContext The callbacks context specified in VRDEGetInterface. diff --git a/include/VBox/RemoteDesktop/VRDEInput.h b/include/VBox/RemoteDesktop/VRDEInput.h new file mode 100644 index 00000000..093591e2 --- /dev/null +++ b/include/VBox/RemoteDesktop/VRDEInput.h @@ -0,0 +1,220 @@ +/** @file + * VBox Remote Desktop Extension (VRDE) - Input interface. + */ + +/* + * 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 ___VBox_RemoteDesktop_VRDEInput_h +#define ___VBox_RemoteDesktop_VRDEInput_h + + +/* + * Interface for receiving input events from the client. + */ + +/* All structures in this file are packed. + * Everything is little-endian. + */ +#pragma pack(1) + +/* + * The application interface between VirtualBox and the VRDE server. + */ + +#define VRDE_INPUT_INTERFACE_NAME "VRDE::INPUT" + +/* + * Supported input methods. + */ +#define VRDE_INPUT_METHOD_TOUCH 1 + +/* + * fu32Flags for VRDEInputSetup + */ +#define VRDE_INPUT_F_ENABLE 1 + +/* The interface entry points. Interface version 1. */ +typedef struct VRDEINPUTINTERFACE +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* Tell the server that an input method will be used or disabled, etc. + * VRDECallbackInputSetup will be called with a result. + * + * @param hServer The VRDE server instance. + * @param u32Method The method VRDE_INPUT_METHOD_*. + * @param fu32Flags What to do with the method VRDE_INPUT_F_*. + * @param pvSetup Method specific parameters (optional). + * @param cbSetup Size of method specific parameters (optional). + */ + DECLR3CALLBACKMEMBER(void, VRDEInputSetup, (HVRDESERVER hServer, + uint32_t u32Method, + uint32_t fu32Flags, + const void *pvSetup, + uint32_t cbSetup)); +} VRDEINPUTINTERFACE; + + +/* Interface callbacks. */ +typedef struct VRDEINPUTCALLBACKS +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* VRDPInputSetup async result. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcSetup The result code of the request. + * @param u32Method The method VRDE_INPUT_METHOD_*. + * @param pvResult The result information. + * @param cbResult The size of buffer pointed by pvResult. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackInputSetup,(void *pvCallback, + int rcRequest, + uint32_t u32Method, + const void *pvResult, + uint32_t cbResult)); + + /* Input event. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param u32Method The method VRDE_INPUT_METHOD_*. + * @param pvEvent The event data. + * @param cbEvent The size of buffer pointed by pvEvent. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackInputEvent,(void *pvCallback, + uint32_t u32Method, + const void *pvEvent, + uint32_t cbEvent)); +} VRDEINPUTCALLBACKS; + + +/* + * Touch input definitions VRDE_INPUT_METHOD_TOUCH. + */ + +/* pvResult is not used */ + +/* RDPINPUT_HEADER */ +typedef struct VRDEINPUTHEADER +{ + uint16_t u16EventId; + uint32_t u32PDULength; +} VRDEINPUTHEADER; + +/* VRDEINPUTHEADER::u16EventId */ +#define VRDEINPUT_EVENTID_SC_READY 0x0001 +#define VRDEINPUT_EVENTID_CS_READY 0x0002 +#define VRDEINPUT_EVENTID_TOUCH 0x0003 +#define VRDEINPUT_EVENTID_SUSPEND_TOUCH 0x0004 +#define VRDEINPUT_EVENTID_RESUME_TOUCH 0x0005 +#define VRDEINPUT_EVENTID_DISMISS_HOVERING_CONTACT 0x0006 + +/* RDPINPUT_SC_READY_PDU */ +typedef struct VRDEINPUT_SC_READY_PDU +{ + VRDEINPUTHEADER header; + uint32_t u32ProtocolVersion; +} VRDEINPUT_SC_READY_PDU; + +#define VRDEINPUT_PROTOCOL_V1 0x00010000 +#define VRDEINPUT_PROTOCOL_V101 0x00010001 + +/* RDPINPUT_CS_READY_PDU */ +typedef struct VRDEINPUT_CS_READY_PDU +{ + VRDEINPUTHEADER header; + uint32_t u32Flags; + uint32_t u32ProtocolVersion; + uint16_t u16MaxTouchContacts; +} VRDEINPUT_CS_READY_PDU; + +#define VRDEINPUT_READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001 +#define VRDEINPUT_READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002 + +/* RDPINPUT_CONTACT_DATA */ +typedef struct VRDEINPUT_CONTACT_DATA +{ + uint8_t u8ContactId; + uint16_t u16FieldsPresent; + int32_t i32X; + int32_t i32Y; + uint32_t u32ContactFlags; + int16_t i16ContactRectLeft; + int16_t i16ContactRectTop; + int16_t i16ContactRectRight; + int16_t i16ContactRectBottom; + uint32_t u32Orientation; + uint32_t u32Pressure; +} VRDEINPUT_CONTACT_DATA; + +#define VRDEINPUT_CONTACT_DATA_CONTACTRECT_PRESENT 0x0001 +#define VRDEINPUT_CONTACT_DATA_ORIENTATION_PRESENT 0x0002 +#define VRDEINPUT_CONTACT_DATA_PRESSURE_PRESENT 0x0004 + +#define VRDEINPUT_CONTACT_FLAG_DOWN 0x0001 +#define VRDEINPUT_CONTACT_FLAG_UPDATE 0x0002 +#define VRDEINPUT_CONTACT_FLAG_UP 0x0004 +#define VRDEINPUT_CONTACT_FLAG_INRANGE 0x0008 +#define VRDEINPUT_CONTACT_FLAG_INCONTACT 0x0010 +#define VRDEINPUT_CONTACT_FLAG_CANCELED 0x0020 + +/* RDPINPUT_TOUCH_FRAME */ +typedef struct VRDEINPUT_TOUCH_FRAME +{ + uint16_t u16ContactCount; + uint64_t u64FrameOffset; + VRDEINPUT_CONTACT_DATA aContacts[1]; +} VRDEINPUT_TOUCH_FRAME; + +/* RDPINPUT_TOUCH_EVENT_PDU */ +typedef struct VRDEINPUT_TOUCH_EVENT_PDU +{ + VRDEINPUTHEADER header; + uint32_t u32EncodeTime; + uint16_t u16FrameCount; + VRDEINPUT_TOUCH_FRAME aFrames[1]; +} VRDEINPUT_TOUCH_EVENT_PDU; + +/* RDPINPUT_SUSPEND_TOUCH_PDU */ +typedef struct VRDEINPUT_SUSPEND_TOUCH_PDU +{ + VRDEINPUTHEADER header; +} VRDEINPUT_SUSPEND_TOUCH_PDU; + +/* RDPINPUT_RESUME_TOUCH_PDU */ +typedef struct VRDEINPUT_RESUME_TOUCH_PDU +{ + VRDEINPUTHEADER header; +} VRDEINPUT_RESUME_TOUCH_PDU; + +/* RDPINPUT_DISMISS_HOVERING_CONTACT_PDU */ +typedef struct VRDEINPUT_DISMISS_HOVERING_CONTACT_PDU +{ + VRDEINPUTHEADER header; + uint8_t u8ContactId; +} VRDEINPUT_DISMISS_HOVERING_CONTACT_PDU; + +#pragma pack() + +#endif diff --git a/include/VBox/RemoteDesktop/VRDEVideoIn.h b/include/VBox/RemoteDesktop/VRDEVideoIn.h new file mode 100644 index 00000000..0ff12f56 --- /dev/null +++ b/include/VBox/RemoteDesktop/VRDEVideoIn.h @@ -0,0 +1,1078 @@ +/** @file + * VBox Remote Desktop Extension (VRDE) - Video Input interface. + */ + +/* + * Copyright (C) 2012-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 ___VBox_RemoteDesktop_VRDEVideoIn_h +#define ___VBox_RemoteDesktop_VRDEVideoIn_h + + +/* Define VRDE_VIDEOIN_WITH_VRDEINTERFACE to include the server VRDE interface parts. */ + +#ifdef VRDE_VIDEOIN_WITH_VRDEINTERFACE +#include +#endif /* VRDE_VIDEOIN_WITH_VRDEINTERFACE */ + +#ifdef AssertCompileSize +#define ASSERTSIZE(type, size) AssertCompileSize(type, size); +#else +#define ASSERTSIZE(type, size) +#endif /* AssertCompileSize */ + + +/* + * Interface for accessing a video camera device on the client. + * + * Async callbacks are used for providing feedback, reporting errors, etc. + * + * Initial version supports: Camera + Processing Unit + Streaming Control. + * + * There are 2 modes: + * 1) The virtual WebCam is already attached to the guest. + * 2) The virtual WebCam will be attached when the client has it. + * + * Initially the mode 1 is supported. + * + * Mode 1 details: + * The WebCam has some fixed functionality, according to the descriptors, + * which has been already read by the guest. So some of functions will + * not work if the client does not support them. + * + * Mode 2 details: + * Virtual WebCam descriptors are built from the client capabilities. + * + * Similarly to the smartcard, the server will inform the ConsoleVRDE that there is a WebCam. + * ConsoleVRDE creates a VRDEVIDEOIN handle and forwards virtual WebCam requests to it. + * + * Interface with VBox. + * + * Virtual WebCam ConsoleVRDE VRDE + * + * Negotiate <-> + * <- VideoInDeviceNotify(Attached, DeviceId) + * -> GetDeviceDesc + * <- DeviceDesc + * 2 <- CreateCamera + * 2 CameraCreated -> + * + * CameraRequest -> Request -> + * Response <- <- Response <- Response + * Frame <- <- Frame <- Frame + * <- VideoInDeviceNotify(Detached, DeviceId) + * + * Unsupported requests fail. + * The Device Description received from the client may be used to validate WebCam requests + * in the ConsoleVRDE code, for example filter out unsupported requests. + * + */ + +/* All structures in this file are packed. + * Everything is little-endian. + */ +#pragma pack(1) + +/* + * The interface supports generic video input descriptors, capabilities and controls: + * * Descriptors + * + Interface + * - Input, Camera Terminal + * - Processing Unit + * + Video Streaming + * - Input Header + * - Payload Format + * - Video Frame + * - Still Image Frame + * * Video Control requests + * + Interface + * - Power Mode + * + Unit and Terminal + * camera + * - Scanning Mode (interlaced, progressive) + * - Auto-Exposure Mode + * - Auto-Exposure Priority + * - Exposure Time Absolute, Relative + * - Focus Absolute, Relative, Auto + * - Iris Absolute, Relative + * - Zoom Absolute, Relative + * - PanTilt Absolute, Relative + * - Roll Absolute, Relative + * - Privacy + * processing + * - Backlight Compensation + * - Brightness + * - Contrast + * - Gain + * - Power Line Frequency + * - Hue Manual, Auto + * - Saturation + * - Sharpness + * - Gamma + * - White Balance Temperature Manual, Auto + * - White Balance Component Manual, Auto + * - Digital Multiplier + * - Digital Multiplier Limit + * * Video Streaming requests + * + Interface + * - Synch Delay + * - Still Image Trigger + * - Generate Key Frame + * - Update Frame Segment + * - Stream Error Code + * + * + * Notes: + * * still capture uses a method similar to method 2, because the still frame will + * be send instead of video over the channel. + * Also the method 2 can be in principle emulated by both 1 and 3 on the client. + * However the client can initiate a still frame transfer, similar to hardware button trigger. + * * all control changes are async. + * * probe/commit are not used. The server can select a supported format/frame from the list. + * * no color matching. sRGB is the default. + * * most of constants are the same as in USB Video Class spec, but they are not the same and + * should be always converted. + */ + +/* + * The DEVICEDEC describes the device and provides a list of supported formats: + * VRDEVIDEOINDEVICEDESC + * VRDEVIDEOINFORMATDESC[0]; + * VRDEVIDEOINFRAMEDESC[0..N-1] + * VRDEVIDEOINFORMATDESC[1]; + * VRDEVIDEOINFRAMEDESC[0..M-1] + * ... + */ + +typedef struct VRDEVIDEOINDEVICEDESC +{ + uint16_t u16ObjectiveFocalLengthMin; + uint16_t u16ObjectiveFocalLengthMax; + uint16_t u16OcularFocalLength; + uint16_t u16MaxMultiplier; + uint32_t fu32CameraControls; /* VRDE_VIDEOIN_F_CT_CTRL_* */ + uint32_t fu32ProcessingControls; /* VRDE_VIDEOIN_F_PU_CTRL_* */ + uint8_t fu8DeviceCaps; /* VRDE_VIDEOIN_F_DEV_CAP_* */ + uint8_t u8NumFormats; /* Number of following VRDEVIDEOINFORMATDESC structures. */ + uint16_t cbExt; /* Size of the optional extended description. */ + /* An extended description may follow. */ + /* An array of VRDEVIDEOINFORMATDESC follows. */ +} VRDEVIDEOINDEVICEDESC; + +/* VRDEVIDEOINDEVICEDESC::fu32CameraControls */ +#define VRDE_VIDEOIN_F_CT_CTRL_SCANNING_MODE 0x00000001 /* D0: Scanning Mode */ +#define VRDE_VIDEOIN_F_CT_CTRL_AE_MODE 0x00000002 /* D1: Auto-Exposure Mode */ +#define VRDE_VIDEOIN_F_CT_CTRL_AE_PRIORITY 0x00000004 /* D2: Auto-Exposure Priority */ +#define VRDE_VIDEOIN_F_CT_CTRL_EXPOSURE_TIME_ABSOLUTE 0x00000008 /* D3: Exposure Time (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_EXPOSURE_TIME_RELATIVE 0x00000010 /* D4: Exposure Time (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_FOCUS_ABSOLUTE 0x00000020 /* D5: Focus (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_FOCUS_RELATIVE 0x00000040 /* D6: Focus (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_IRIS_ABSOLUTE 0x00000080 /* D7: Iris (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_IRIS_RELATIVE 0x00000100 /* D8: Iris (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ZOOM_ABSOLUTE 0x00000200 /* D9: Zoom (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ZOOM_RELATIVE 0x00000400 /* D10: Zoom (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_PANTILT_ABSOLUTE 0x00000800 /* D11: PanTilt (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_PANTILT_RELATIVE 0x00001000 /* D12: PanTilt (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ROLL_ABSOLUTE 0x00002000 /* D13: Roll (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ROLL_RELATIVE 0x00004000 /* D14: Roll (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_RESERVED1 0x00008000 /* D15: Reserved */ +#define VRDE_VIDEOIN_F_CT_CTRL_RESERVED2 0x00010000 /* D16: Reserved */ +#define VRDE_VIDEOIN_F_CT_CTRL_FOCUS_AUTO 0x00020000 /* D17: Focus, Auto */ +#define VRDE_VIDEOIN_F_CT_CTRL_PRIVACY 0x00040000 /* D18: Privacy */ + +/* VRDEVIDEOINDEVICEDESC::fu32ProcessingControls */ +#define VRDE_VIDEOIN_F_PU_CTRL_BRIGHTNESS 0x00000001 /* D0: Brightness */ +#define VRDE_VIDEOIN_F_PU_CTRL_CONTRAST 0x00000002 /* D1: Contrast */ +#define VRDE_VIDEOIN_F_PU_CTRL_HUE 0x00000004 /* D2: Hue */ +#define VRDE_VIDEOIN_F_PU_CTRL_SATURATION 0x00000008 /* D3: Saturation */ +#define VRDE_VIDEOIN_F_PU_CTRL_SHARPNESS 0x00000010 /* D4: Sharpness */ +#define VRDE_VIDEOIN_F_PU_CTRL_GAMMA 0x00000020 /* D5: Gamma */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_TEMPERATURE 0x00000040 /* D6: White Balance Temperature */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_COMPONENT 0x00000080 /* D7: White Balance Component */ +#define VRDE_VIDEOIN_F_PU_CTRL_BACKLIGHT_COMPENSATION 0x00000100 /* D8: Backlight Compensation */ +#define VRDE_VIDEOIN_F_PU_CTRL_GAIN 0x00000200 /* D9: Gain */ +#define VRDE_VIDEOIN_F_PU_CTRL_POWER_LINE_FREQUENCY 0x00000400 /* D10: Power Line Frequency */ +#define VRDE_VIDEOIN_F_PU_CTRL_HUE_AUTO 0x00000800 /* D11: Hue, Auto */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_TEMPERATURE_AUTO 0x00001000 /* D12: White Balance Temperature, Auto */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_COMPONENT_AUTO 0x00002000 /* D13: White Balance Component, Auto */ +#define VRDE_VIDEOIN_F_PU_CTRL_DIGITAL_MULTIPLIER 0x00004000 /* D14: Digital Multiplier */ +#define VRDE_VIDEOIN_F_PU_CTRL_DIGITAL_MULTIPLIER_LIMIT 0x00008000 /* D15: Digital Multiplier Limit */ + +/* VRDEVIDEOINDEVICEDESC::fu8DeviceCaps */ +#define VRDE_VIDEOIN_F_DEV_CAP_DYNAMICCHANGE 0x01 /* Whether dynamic format change is supported. */ +#define VRDE_VIDEOIN_F_DEV_CAP_TRIGGER 0x02 /* Whether hardware triggering is supported. */ +#define VRDE_VIDEOIN_F_DEV_CAP_TRIGGER_USAGE 0x04 /* 0 - still image, 1 - generic button event.*/ + +/* VRDEVIDEOINDEVICEDESC extended description. */ +typedef struct VRDEVIDEOINDEVICEEXT +{ + uint32_t fu32Fields; + /* One or more VRDEVIDEOINDEVICEFIELD follow. */ +} VRDEVIDEOINDEVICEEXT; + +typedef struct VRDEVIDEOINDEVICEFIELDHDR +{ + uint16_t cbField; /* Number of bytes reserved for this field. */ +} VRDEVIDEOINDEVICEFIELDHDR; + +/* VRDEVIDEOINDEVICEDESC::fu32Fields */ +#define VRDE_VIDEOIN_F_DEV_EXT_NAME 0x00000001 /* Utf8 device name. */ +#define VRDE_VIDEOIN_F_DEV_EXT_SERIAL 0x00000002 /* Utf8 device serial number. */ + +/* The video format descriptor. */ +typedef struct VRDEVIDEOINFORMATDESC +{ + uint16_t cbFormat; /* Size of the structure including cbFormat and format specific data. */ + uint8_t u8FormatId; /* The unique identifier of the format on the client. */ + uint8_t u8FormatType; /* MJPEG etc. VRDE_VIDEOIN_FORMAT_* */ + uint8_t u8FormatFlags; /* VRDE_VIDEOIN_F_FMT_* */ + uint8_t u8NumFrames; /* Number of following VRDEVIDEOINFRAMEDESC structures. */ + uint16_t u16Reserved; /* Must be set to 0. */ + /* Other format specific data may follow. */ + /* An array of VRDEVIDEOINFRAMEDESC follows. */ +} VRDEVIDEOINFORMATDESC; + +/* VRDEVIDEOINFORMATDESC::u8FormatType */ +#define VRDE_VIDEOIN_FORMAT_UNCOMPRESSED 0x04 +#define VRDE_VIDEOIN_FORMAT_MJPEG 0x06 +#define VRDE_VIDEOIN_FORMAT_MPEG2TS 0x0A +#define VRDE_VIDEOIN_FORMAT_DV 0x0C +#define VRDE_VIDEOIN_FORMAT_FRAME_BASED 0x10 +#define VRDE_VIDEOIN_FORMAT_STREAM_BASED 0x12 + +/* VRDEVIDEOINFORMATDESC::u8FormatFlags. */ +#define VRDE_VIDEOIN_F_FMT_GENERATEKEYFRAME 0x01 /* Supports Generate Key Frame */ +#define VRDE_VIDEOIN_F_FMT_UPDATEFRAMESEGMENT 0x02 /* Supports Update Frame Segment */ +#define VRDE_VIDEOIN_F_FMT_COPYPROTECT 0x04 /* If duplication should be restricted. */ +#define VRDE_VIDEOIN_F_FMT_COMPQUALITY 0x08 /* If the format supports an adjustable compression quality. */ + +typedef struct VRDEVIDEOINFRAMEDESC +{ + uint16_t cbFrame; /* Size of the structure including cbFrame and frame specific data. */ + uint8_t u8FrameId; /* The unique identifier of the frame for the corresponding format on the client. */ + uint8_t u8FrameFlags; + uint16_t u16Width; + uint16_t u16Height; + uint32_t u32NumFrameIntervals; /* The number of supported frame intervals. */ + uint32_t u32MinFrameInterval; /* Shortest frame interval supported (at highest frame rate), in 100ns units. */ + uint32_t u32MaxFrameInterval; /* Longest frame interval supported (at lowest frame rate), in 100ns units. */ + /* Supported frame intervals (in 100ns units) follow if VRDE_VIDEOIN_F_FRM_DISCRETE_INTERVALS is set. + * uint32_t au32FrameIntervals[u32NumFrameIntervals]; + */ + /* Supported min and max bitrate in bits per second follow if VRDE_VIDEOIN_F_FRM_BITRATE is set. + * uint32_t u32MinBitRate; + * uint32_t u32MaxBitRate; + */ + /* Other frame specific data may follow. */ +} VRDEVIDEOINFRAMEDESC; + +/* VRDEVIDEOINFRAMEDESC::u8FrameFlags. */ +#define VRDE_VIDEOIN_F_FRM_STILL 0x01 /* If still images are supported for this frame. */ +#define VRDE_VIDEOIN_F_FRM_DISCRETE_INTERVALS 0x02 /* If the discrete intervals list is included. */ +#define VRDE_VIDEOIN_F_FRM_BITRATE 0x04 /* If the bitrate fields are included. */ +#define VRDE_VIDEOIN_F_FRM_SIZE_OF_FIELDS 0x08 /* If the all optional fields start with 16 bit field size. */ + +/* + * Controls. + * + * The same structures are used for both SET and GET requests. + * Requests are async. A callback is invoked, when the client returns a reply. + * A control change notification also uses these structures. + * + * If a control request can not be fulfilled, then VRDE_VIDEOIN_CTRLHDR_F_FAIL + * will be set and u8Status contains the error code. This replaces the VC_REQUEST_ERROR_CODE_CONTROL. + * + * If the client receives an unsupported control, then the client must ignore it. + * That is the control request must not affect the client in any way. + * The client may send a VRDEVIDEOINCTRLHDR response for the unsupported control with: + * u16ControlSelector = the received value; + * u16RequestType = the received value; + * u16ParmSize = 0; + * u8Flags = VRDE_VIDEOIN_CTRLHDR_F_FAIL; + * u8Status = VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDCONTROL; + */ + +typedef struct VRDEVIDEOINCTRLHDR +{ + uint16_t u16ControlSelector; /* VRDE_VIDEOIN_CTRLSEL_* */ + uint16_t u16RequestType; /* VRDE_VIDEOIN_CTRLREQ_* */ + uint16_t u16ParmSize; /* The size of the control specific parameters. */ + uint8_t u8Flags; /* VRDE_VIDEOIN_CTRLHDR_F_* */ + uint8_t u8Status; /* VRDE_VIDEOIN_CTRLHDR_STATUS_* */ + /* Control specific data follows. */ +} VRDEVIDEOINCTRLHDR; + +/* Control request types: VRDEVIDEOINCTRLHDR::u16RequestType. */ +#define VRDE_VIDEOIN_CTRLREQ_UNDEFINED 0x00 +#define VRDE_VIDEOIN_CTRLREQ_SET_CUR 0x01 +#define VRDE_VIDEOIN_CTRLREQ_GET_CUR 0x81 +#define VRDE_VIDEOIN_CTRLREQ_GET_MIN 0x82 +#define VRDE_VIDEOIN_CTRLREQ_GET_MAX 0x83 +#define VRDE_VIDEOIN_CTRLREQ_GET_RES 0x84 +#define VRDE_VIDEOIN_CTRLREQ_GET_LEN 0x85 +#define VRDE_VIDEOIN_CTRLREQ_GET_INFO 0x86 +#define VRDE_VIDEOIN_CTRLREQ_GET_DEF 0x87 + +/* VRDEVIDEOINCTRLHDR::u8Flags */ +#define VRDE_VIDEOIN_CTRLHDR_F_NOTIFY 0x01 /* Control change notification, the attribute is derived from u16RequestType and F_FAIL. */ +#define VRDE_VIDEOIN_CTRLHDR_F_FAIL 0x02 /* The operation failed. Error code is in u8Status. */ + +/* VRDEVIDEOINCTRLHDR::u8Status if the VRDE_VIDEOIN_CTRLHDR_F_FAIL is set. */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_SUCCESS 0x00 /**/ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_NOTREADY 0x01 /* Not ready */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_WRONGSTATE 0x02 /* Wrong state */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_POWER 0x03 /* Power */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_OUTOFRANGE 0x04 /* Out of range */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDUNIT 0x05 /* Invalid unit */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDCONTROL 0x06 /* Invalid control */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDREQUEST 0x07 /* Invalid request */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_UNKNOWN 0xFF /* Unknown */ + +/* Control selectors. 16 bit. High byte is the category. Low byte is the identifier.*/ +#ifdef RT_MAKE_U16 +#define VRDE_VIDEOIN_CTRLSEL_MAKE(Lo, Hi) RT_MAKE_U16(Lo, Hi) +#else +#define VRDE_VIDEOIN_CTRLSEL_MAKE(Lo, Hi) ((uint16_t)( (uint16_t)((uint8_t)(Hi)) << 8 | (uint8_t)(Lo) )) +#endif + +#define VRDE_VIDEOIN_CTRLSEL_VC(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x01) +#define VRDE_VIDEOIN_CTRLSEL_CT(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x02) +#define VRDE_VIDEOIN_CTRLSEL_PU(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x03) +#define VRDE_VIDEOIN_CTRLSEL_VS(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x04) +#define VRDE_VIDEOIN_CTRLSEL_HW(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x05) +#define VRDE_VIDEOIN_CTRLSEL_PROT(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x06) + +#define VRDE_VIDEOIN_CTRLSEL_VC_VIDEO_POWER_MODE_CONTROL VRDE_VIDEOIN_CTRLSEL_VC(0x01) + +#define VRDE_VIDEOIN_CTRLSEL_CT_UNDEFINED VRDE_VIDEOIN_CTRLSEL_CT(0x00) +#define VRDE_VIDEOIN_CTRLSEL_CT_SCANNING_MODE VRDE_VIDEOIN_CTRLSEL_CT(0x01) +#define VRDE_VIDEOIN_CTRLSEL_CT_AE_MODE VRDE_VIDEOIN_CTRLSEL_CT(0x02) +#define VRDE_VIDEOIN_CTRLSEL_CT_AE_PRIORITY VRDE_VIDEOIN_CTRLSEL_CT(0x03) +#define VRDE_VIDEOIN_CTRLSEL_CT_EXPOSURE_TIME_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x04) +#define VRDE_VIDEOIN_CTRLSEL_CT_EXPOSURE_TIME_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x05) +#define VRDE_VIDEOIN_CTRLSEL_CT_FOCUS_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x06) +#define VRDE_VIDEOIN_CTRLSEL_CT_FOCUS_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x07) +#define VRDE_VIDEOIN_CTRLSEL_CT_FOCUS_AUTO VRDE_VIDEOIN_CTRLSEL_CT(0x08) +#define VRDE_VIDEOIN_CTRLSEL_CT_IRIS_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x09) +#define VRDE_VIDEOIN_CTRLSEL_CT_IRIS_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x0A) +#define VRDE_VIDEOIN_CTRLSEL_CT_ZOOM_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x0B) +#define VRDE_VIDEOIN_CTRLSEL_CT_ZOOM_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x0C) +#define VRDE_VIDEOIN_CTRLSEL_CT_PANTILT_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x0D) +#define VRDE_VIDEOIN_CTRLSEL_CT_PANTILT_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x0E) +#define VRDE_VIDEOIN_CTRLSEL_CT_ROLL_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x0F) +#define VRDE_VIDEOIN_CTRLSEL_CT_ROLL_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x10) +#define VRDE_VIDEOIN_CTRLSEL_CT_PRIVACY VRDE_VIDEOIN_CTRLSEL_CT(0x11) + +#define VRDE_VIDEOIN_CTRLSEL_PU_UNDEFINED VRDE_VIDEOIN_CTRLSEL_PU(0x00) +#define VRDE_VIDEOIN_CTRLSEL_PU_BACKLIGHT_COMPENSATION VRDE_VIDEOIN_CTRLSEL_PU(0x01) +#define VRDE_VIDEOIN_CTRLSEL_PU_BRIGHTNESS VRDE_VIDEOIN_CTRLSEL_PU(0x02) +#define VRDE_VIDEOIN_CTRLSEL_PU_CONTRAST VRDE_VIDEOIN_CTRLSEL_PU(0x03) +#define VRDE_VIDEOIN_CTRLSEL_PU_GAIN VRDE_VIDEOIN_CTRLSEL_PU(0x04) +#define VRDE_VIDEOIN_CTRLSEL_PU_POWER_LINE_FREQUENCY VRDE_VIDEOIN_CTRLSEL_PU(0x05) +#define VRDE_VIDEOIN_CTRLSEL_PU_HUE VRDE_VIDEOIN_CTRLSEL_PU(0x06) +#define VRDE_VIDEOIN_CTRLSEL_PU_SATURATION VRDE_VIDEOIN_CTRLSEL_PU(0x07) +#define VRDE_VIDEOIN_CTRLSEL_PU_SHARPNESS VRDE_VIDEOIN_CTRLSEL_PU(0x08) +#define VRDE_VIDEOIN_CTRLSEL_PU_GAMMA VRDE_VIDEOIN_CTRLSEL_PU(0x09) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_TEMPERATURE VRDE_VIDEOIN_CTRLSEL_PU(0x0A) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_TEMPERATURE_AUTO VRDE_VIDEOIN_CTRLSEL_PU(0x0B) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_COMPONENT VRDE_VIDEOIN_CTRLSEL_PU(0x0C) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_COMPONENT_AUTO VRDE_VIDEOIN_CTRLSEL_PU(0x0D) +#define VRDE_VIDEOIN_CTRLSEL_PU_DIGITAL_MULTIPLIER VRDE_VIDEOIN_CTRLSEL_PU(0x0E) +#define VRDE_VIDEOIN_CTRLSEL_PU_DIGITAL_MULTIPLIER_LIMIT VRDE_VIDEOIN_CTRLSEL_PU(0x0F) +#define VRDE_VIDEOIN_CTRLSEL_PU_HUE_AUTO VRDE_VIDEOIN_CTRLSEL_PU(0x10) +#define VRDE_VIDEOIN_CTRLSEL_PU_ANALOG_VIDEO_STANDARD VRDE_VIDEOIN_CTRLSEL_PU(0x11) +#define VRDE_VIDEOIN_CTRLSEL_PU_ANALOG_LOCK_STATUS VRDE_VIDEOIN_CTRLSEL_PU(0x12) + +#define VRDE_VIDEOIN_CTRLSEL_VS_UNDEFINED VRDE_VIDEOIN_CTRLSEL_VS(0x00) +#define VRDE_VIDEOIN_CTRLSEL_VS_SETUP VRDE_VIDEOIN_CTRLSEL_VS(0x01) +#define VRDE_VIDEOIN_CTRLSEL_VS_OFF VRDE_VIDEOIN_CTRLSEL_VS(0x02) +#define VRDE_VIDEOIN_CTRLSEL_VS_ON VRDE_VIDEOIN_CTRLSEL_VS(0x03) +#define VRDE_VIDEOIN_CTRLSEL_VS_STILL_IMAGE_TRIGGER VRDE_VIDEOIN_CTRLSEL_VS(0x05) +#define VRDE_VIDEOIN_CTRLSEL_VS_STREAM_ERROR_CODE VRDE_VIDEOIN_CTRLSEL_VS(0x06) +#define VRDE_VIDEOIN_CTRLSEL_VS_GENERATE_KEY_FRAME VRDE_VIDEOIN_CTRLSEL_VS(0x07) +#define VRDE_VIDEOIN_CTRLSEL_VS_UPDATE_FRAME_SEGMENT VRDE_VIDEOIN_CTRLSEL_VS(0x08) +#define VRDE_VIDEOIN_CTRLSEL_VS_SYNCH_DELAY VRDE_VIDEOIN_CTRLSEL_VS(0x09) + +#define VRDE_VIDEOIN_CTRLSEL_HW_BUTTON VRDE_VIDEOIN_CTRLSEL_HW(0x01) + +#define VRDE_VIDEOIN_CTRLSEL_PROT_PING VRDE_VIDEOIN_CTRLSEL_PROT(0x01) +#define VRDE_VIDEOIN_CTRLSEL_PROT_SAMPLING VRDE_VIDEOIN_CTRLSEL_PROT(0x02) +#define VRDE_VIDEOIN_CTRLSEL_PROT_FRAMES VRDE_VIDEOIN_CTRLSEL_PROT(0x03) + +typedef struct VRDEVIDEOINCTRL_VIDEO_POWER_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8DevicePowerMode; +} VRDEVIDEOINCTRL_VIDEO_POWER_MODE; + +typedef struct VRDEVIDEOINCTRL_CT_SCANNING_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8ScanningMode; +} VRDEVIDEOINCTRL_CT_SCANNING_MODE; + +typedef struct VRDEVIDEOINCTRL_CT_AE_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8AutoExposureMode; +} VRDEVIDEOINCTRL_CT_AE_MODE; + +typedef struct VRDEVIDEOINCTRL_CT_AE_PRIORITY +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8AutoExposurePriority; +} VRDEVIDEOINCTRL_CT_AE_PRIORITY; + +typedef struct VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t u32ExposureTimeAbsolute; +} VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8ExposureTimeRelative; +} VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_FOCUS_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16FocusAbsolute; +} VRDEVIDEOINCTRL_CT_FOCUS_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_FOCUS_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8FocusRelative; + uint8_t u8Speed; +} VRDEVIDEOINCTRL_CT_FOCUS_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_FOCUS_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8FocusAuto; +} VRDEVIDEOINCTRL_CT_FOCUS_AUTO; + +typedef struct VRDEVIDEOINCTRL_CT_IRIS_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16IrisAbsolute; +} VRDEVIDEOINCTRL_CT_IRIS_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_IRIS_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8IrisRelative; +} VRDEVIDEOINCTRL_CT_IRIS_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_ZOOM_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16ZoomAbsolute; +} VRDEVIDEOINCTRL_CT_ZOOM_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_ZOOM_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Zoom; + uint8_t u8DigitalZoom; + uint8_t u8Speed; +} VRDEVIDEOINCTRL_CT_ZOOM_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_PANTILT_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t u32PanAbsolute; + uint32_t u32TiltAbsolute; +} VRDEVIDEOINCTRL_CT_PANTILT_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_PANTILT_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8PanRelative; + uint8_t u8PanSpeed; + uint8_t u8TiltRelative; + uint8_t u8TiltSpeed; +} VRDEVIDEOINCTRL_CT_PANTILT_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_ROLL_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16RollAbsolute; +} VRDEVIDEOINCTRL_CT_ROLL_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_ROLL_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8RollRelative; + uint8_t u8Speed; +} VRDEVIDEOINCTRL_CT_ROLL_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_PRIVACY_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Privacy; +} VRDEVIDEOINCTRL_CT_PRIVACY_MODE; + +typedef struct VRDEVIDEOINCTRL_PU_BACKLIGHT_COMPENSATION +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16BacklightCompensation; +} VRDEVIDEOINCTRL_PU_BACKLIGHT_COMPENSATION; + +typedef struct VRDEVIDEOINCTRL_PU_BRIGHTNESS +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Brightness; +} VRDEVIDEOINCTRL_PU_BRIGHTNESS; + +typedef struct VRDEVIDEOINCTRL_PU_CONTRAST +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Contrast; +} VRDEVIDEOINCTRL_PU_CONTRAST; + +typedef struct VRDEVIDEOINCTRL_PU_GAIN +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Gain; +} VRDEVIDEOINCTRL_PU_GAIN; + +typedef struct VRDEVIDEOINCTRL_PU_POWER_LINE_FREQUENCY +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16PowerLineFrequency; +} VRDEVIDEOINCTRL_PU_POWER_LINE_FREQUENCY; + +typedef struct VRDEVIDEOINCTRL_PU_HUE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Hue; +} VRDEVIDEOINCTRL_PU_HUE; + +typedef struct VRDEVIDEOINCTRL_PU_HUE_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8HueAuto; +} VRDEVIDEOINCTRL_PU_HUE_AUTO; + +typedef struct VRDEVIDEOINCTRL_PU_SATURATION +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Saturation; +} VRDEVIDEOINCTRL_PU_SATURATION; + +typedef struct VRDEVIDEOINCTRL_PU_SHARPNESS +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Sharpness; +} VRDEVIDEOINCTRL_PU_SHARPNESS; + +typedef struct VRDEVIDEOINCTRL_PU_GAMMA +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Gamma; +} VRDEVIDEOINCTRL_PU_GAMMA; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16WhiteBalanceTemperature; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8WhiteBalanceTemperatureAuto; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE_AUTO; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16WhiteBalanceBlue; + uint16_t u16WhiteBalanceRed; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8WhiteBalanceComponentAuto; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT_AUTO; + +typedef struct VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16MultiplierStep; +} VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER; + +typedef struct VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER_LIMIT +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16MultiplierLimit; +} VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER_LIMIT; + +typedef struct VRDEVIDEOINCTRL_PU_ANALOG_VIDEO_STANDARD +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8VideoStandard; +} VRDEVIDEOINCTRL_PU_ANALOG_VIDEO_STANDARD; + +typedef struct VRDEVIDEOINCTRL_PU_ANALOG_LOCK_STATUS +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Status; +} VRDEVIDEOINCTRL_PU_ANALOG_LOCK_STATUS; + +/* Set streaming parameters. The actual streaming will be enabled by VS_ON. */ +#define VRDEVIDEOINCTRL_F_VS_SETUP_FID 0x01 +#define VRDEVIDEOINCTRL_F_VS_SETUP_EOF 0x02 + +typedef struct VRDEVIDEOINCTRL_VS_SETUP +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8FormatId; /* The format id on the client: VRDEVIDEOINFORMATDESC::u8FormatId. */ + uint8_t u8FramingInfo; /* VRDEVIDEOINCTRL_F_VS_SETUP_*. Set by the client. */ + uint16_t u16Width; + uint16_t u16Height; + uint32_t u32FrameInterval; /* Frame interval in 100 ns units, 0 means a still image capture. + * The client may choose a different interval if this value is + * not supported. + */ + uint16_t u16CompQuality; /* 0 .. 10000 = 0 .. 100%. + * Applicable if the format has VRDE_VIDEOIN_F_FMT_COMPQUALITY, + * otherwise this field is ignored. + */ + uint16_t u16Delay; /* Latency in ms from video data capture to presentation on the channel. + * Set by the client, read by the server. + */ + uint32_t u32ClockFrequency; /* @todo just all clocks in 100ns units? */ +} VRDEVIDEOINCTRL_VS_SETUP; + +/* Stop sending video frames. */ +typedef struct VRDEVIDEOINCTRL_VS_OFF +{ + VRDEVIDEOINCTRLHDR hdr; +} VRDEVIDEOINCTRL_VS_OFF; + +/* Start sending video frames with parameters set by VS_SETUP. */ +typedef struct VRDEVIDEOINCTRL_VS_ON +{ + VRDEVIDEOINCTRLHDR hdr; +} VRDEVIDEOINCTRL_VS_ON; + +typedef struct VRDEVIDEOINCTRL_VS_STILL_IMAGE_TRIGGER +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Trigger; +} VRDEVIDEOINCTRL_VS_STILL_IMAGE_TRIGGER; + +typedef struct VRDEVIDEOINCTRL_VS_STREAM_ERROR_CODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8StreamErrorCode; +} VRDEVIDEOINCTRL_VS_STREAM_ERROR_CODE; + +typedef struct VRDEVIDEOINCTRL_VS_GENERATE_KEY_FRAME +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8GenerateKeyFrame; +} VRDEVIDEOINCTRL_VS_GENERATE_KEY_FRAME; + +typedef struct VRDEVIDEOINCTRL_VS_UPDATE_FRAME_SEGMENT +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8StartFrameSegment; + uint8_t u8EndFrameSegment; +} VRDEVIDEOINCTRL_VS_UPDATE_FRAME_SEGMENT; + +typedef struct VRDEVIDEOINCTRL_VS_SYNCH_DELAY +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Delay; +} VRDEVIDEOINCTRL_VS_SYNCH_DELAY; + +/* A hardware button was pressed/released on the device. */ +typedef struct VRDEVIDEOINCTRL_HW_BUTTON +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Pressed; +} VRDEVIDEOINCTRL_HW_BUTTON; + +typedef struct VRDEVIDEOINCTRL_PROT_PING +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t u32Timestamp; /* Set in the request and the same value must be send back in the response. */ +} VRDEVIDEOINCTRL_PROT_PING; + +typedef struct VRDEVIDEOINCTRL_PROT_SAMPLING +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t fu32SampleStart; /* Which parameters must be sampled VRDEVIDEOINCTRL_F_PROT_SAMPLING_*. */ + uint32_t fu32SampleStop; /* Which parameters to disable VRDEVIDEOINCTRL_F_PROT_SAMPLING_*. + * If both Start and Stop is set, then restart the sampling. + */ + uint32_t u32PeriodMS; /* Sampling period in milliseconds. Applies to all samples in fu32SampleStart. + * Not mandatory, the actual sampling period may be different. + */ +} VRDEVIDEOINCTRL_PROT_SAMPLING; + +#define VRDEVIDEOINCTRL_F_PROT_SAMPLING_FRAMES_SOURCE 0x00000001 /* Periodic VRDEVIDEOINCTRL_PROT_FRAMES samples */ +#define VRDEVIDEOINCTRL_F_PROT_SAMPLING_FRAMES_CLIENT_OUT 0x00000002 /* Periodic VRDEVIDEOINCTRL_PROT_FRAMES samples */ + +typedef struct VRDEVIDEOINCTRL_PROT_FRAMES +{ + VRDEVIDEOINCTRLHDR hdr; /* Note: the message should be sent as VRDE_VIDEOIN_FN_CONTROL_NOTIFY. */ + uint32_t u32Sample; /* Which sample is this, one of VRDEVIDEOINCTRL_F_PROT_SAMPLING_*. */ + uint32_t u32TimestampMS; /* When the period started, milliseconds since the start of sampling. */ + uint32_t u32PeriodMS; /* Actual period during which the frames were counted in milliseconds. + * This may be different from VRDEVIDEOINCTRL_PROT_SAMPLING::u32PeriodMS. + */ + uint32_t u32FramesCount; /* How many frames per u32PeriodMS milliseconds. */ +} VRDEVIDEOINCTRL_PROT_FRAMES; + + +/* + * Payload transfers. How frames are sent to the server: + * the client send a PAYLOAD packet, which has the already set format. + * The server enables the transfers by sending VRDEVIDEOINCTRL_VS_ON. + */ + +/* Payload header */ +typedef struct VRDEVIDEOINPAYLOADHDR +{ + uint8_t u8HeaderLength; /* Entire header. */ + uint8_t u8HeaderInfo; /* VRDE_VIDEOIN_PAYLOAD_F_* */ + uint32_t u32PresentationTime; /* @todo define this */ + uint32_t u32SourceTimeClock; /* @todo At the moment when the frame was sent to the channel. + * Allows the server to measure clock drift. + */ + uint16_t u16Reserved; /* @todo */ +} VRDEVIDEOINPAYLOADHDR; + +/* VRDEVIDEOINPAYLOADHDR::u8HeaderInfo */ +#define VRDE_VIDEOIN_PAYLOAD_F_FID 0x01 /* Frame ID */ +#define VRDE_VIDEOIN_PAYLOAD_F_EOF 0x02 /* End of Frame */ +#define VRDE_VIDEOIN_PAYLOAD_F_PTS 0x04 /* Presentation Time */ +#define VRDE_VIDEOIN_PAYLOAD_F_SCR 0x08 /* Source Clock Reference */ +#define VRDE_VIDEOIN_PAYLOAD_F_RES 0x10 /* Reserved */ +#define VRDE_VIDEOIN_PAYLOAD_F_STI 0x20 /* Still Image */ +#define VRDE_VIDEOIN_PAYLOAD_F_ERR 0x40 /* Error */ +#define VRDE_VIDEOIN_PAYLOAD_F_EOH 0x80 /* End of header */ + + +/* + * The network channel specification. + */ + +/* + * The protocol uses a dynamic RDP channel. + * Everything is little-endian. + */ + +/* The dynamic RDP channel name. */ +#define VRDE_VIDEOIN_CHANNEL "RVIDEOIN" + +/* Major functions. */ +#define VRDE_VIDEOIN_FN_NEGOTIATE 0x0000 /* Version and capabilities check. */ +#define VRDE_VIDEOIN_FN_NOTIFY 0x0001 /* Device attach/detach from the client. */ +#define VRDE_VIDEOIN_FN_DEVICEDESC 0x0002 /* Query device description. */ +#define VRDE_VIDEOIN_FN_CONTROL 0x0003 /* Control the device and start/stop video input. + * This function is used for sending a request and + * the corresponding response. + */ +#define VRDE_VIDEOIN_FN_CONTROL_NOTIFY 0x0004 /* The client reports a control change, etc. + * This function indicated that the message is + * not a response to a CONTROL request. + */ +#define VRDE_VIDEOIN_FN_FRAME 0x0005 /* Frame from the client. */ + +/* Status codes. */ +#define VRDE_VIDEOIN_STATUS_SUCCESS 0 /* Function completed successfully. */ +#define VRDE_VIDEOIN_STATUS_FAILED 1 /* Failed for some reason. */ + +typedef struct VRDEVIDEOINMSGHDR +{ + uint32_t u32Length; /* The length of the message in bytes, including the header. */ + uint32_t u32DeviceId; /* The client's device id. */ + uint32_t u32MessageId; /* Unique id assigned by the server. The client must send a reply with the same id. + * If the client initiates a request, then this must be set to 0, because there is + * currently no client requests, which would require a response from the server. + */ + uint16_t u16FunctionId; /* VRDE_VIDEOIN_FN_* */ + uint16_t u16Status; /* The result of a request. VRDE_VIDEOIN_STATUS_*. */ +} VRDEVIDEOINMSGHDR; +ASSERTSIZE(VRDEVIDEOINMSGHDR, 16) + +/* + * VRDE_VIDEOIN_FN_NEGOTIATE + * + * Sent by the server when the channel is established and the client replies with its capabilities. + */ +#define VRDE_VIDEOIN_NEGOTIATE_VERSION 1 + +/* VRDEVIDEOINMSG_NEGOTIATE::fu32Capabilities */ +#define VRDE_VIDEOIN_NEGOTIATE_CAP_VOID 0x00000000 +#define VRDE_VIDEOIN_NEGOTIATE_CAP_PROT 0x00000001 /* Supports VRDE_VIDEOIN_CTRLSEL_PROT_* controls. */ + +typedef struct VRDEVIDEOINMSG_NEGOTIATE +{ + VRDEVIDEOINMSGHDR hdr; + uint32_t u32Version; /* VRDE_VIDEOIN_NEGOTIATE_VERSION */ + uint32_t fu32Capabilities; /* VRDE_VIDEOIN_NEGOTIATE_CAP_* */ +} VRDEVIDEOINMSG_NEGOTIATE; + +/* + * VRDE_VIDEOIN_FN_NOTIFY + * + * Sent by the client when a webcam is attached or detached. + * The client must send the ATTACH notification for each webcam, which is + * already connected to the client when the VIDEOIN channel is established. + */ +#define VRDE_VIDEOIN_NOTIFY_EVENT_ATTACH 0 +#define VRDE_VIDEOIN_NOTIFY_EVENT_DETACH 1 +#define VRDE_VIDEOIN_NOTIFY_EVENT_NEGOTIATE 2 /* Negotiate again with the client. */ + +typedef struct VRDEVIDEOINMSG_NOTIFY +{ + VRDEVIDEOINMSGHDR hdr; + uint32_t u32NotifyEvent; /* VRDE_VIDEOIN_NOTIFY_EVENT_* */ + /* Event specific data may follow. The underlying protocol provides the length of the message. */ +} VRDEVIDEOINMSG_NOTIFY; + +/* + * VRDE_VIDEOIN_FN_DEVICEDESC + * + * The server queries the description of a device. + */ +typedef struct VRDEVIDEOINMSG_DEVICEDESC_REQ +{ + VRDEVIDEOINMSGHDR hdr; +} VRDEVIDEOINMSG_DEVICEDESC_REQ; + +typedef struct VRDEVIDEOINMSG_DEVICEDESC_RSP +{ + VRDEVIDEOINMSGHDR hdr; + VRDEVIDEOINDEVICEDESC Device; + /* + * VRDEVIDEOINFORMATDESC[0] + * VRDEVIDEOINFRAMEDESC[0] + * ... + * VRDEVIDEOINFRAMEDESC[n] + * VRDEVIDEOINFORMATDESC[1] + * VRDEVIDEOINFRAMEDESC[0] + * ... + * VRDEVIDEOINFRAMEDESC[m] + * ... + */ +} VRDEVIDEOINMSG_DEVICEDESC_RSP; + +/* + * VRDE_VIDEOIN_FN_CONTROL + * VRDE_VIDEOIN_FN_CONTROL_NOTIFY + * + * Either sent by the server or by the client as a notification/response. + * If sent by the client as a notification, then hdr.u32MessageId must be 0. + */ +typedef struct VRDEVIDEOINMSG_CONTROL +{ + VRDEVIDEOINMSGHDR hdr; + VRDEVIDEOINCTRLHDR Control; + /* Control specific data may follow. */ +} VRDEVIDEOINMSG_CONTROL; + +/* + * VRDE_VIDEOIN_FN_FRAME + * + * The client sends a video/still frame in the already specified format. + * hdr.u32MessageId must be 0. + */ +typedef struct VRDEVIDEOINMSG_FRAME +{ + VRDEVIDEOINMSGHDR hdr; + VRDEVIDEOINPAYLOADHDR Payload; + /* The frame data follow. */ +} VRDEVIDEOINMSG_FRAME; + + +#ifdef VRDE_VIDEOIN_WITH_VRDEINTERFACE +/* + * The application interface between VirtualBox and the VRDE server. + */ + +#define VRDE_VIDEOIN_INTERFACE_NAME "VIDEOIN" + +typedef struct VRDEVIDEOINDEVICEHANDLE +{ + uint32_t u32ClientId; + uint32_t u32DeviceId; +} VRDEVIDEOINDEVICEHANDLE; + +/* The VRDE server video input interface entry points. Interface version 1. */ +typedef struct VRDEVIDEOININTERFACE +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* Tell the server that this device will be used and associate a context with the device. + * + * @param hServer The VRDE server instance. + * @param pDeviceHandle The device reported by ATTACH notification. + * @param pvDeviceCtx The caller context associated with the pDeviceHandle. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInDeviceAttach, (HVRDESERVER hServer, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, + void *pvDeviceCtx)); + + /* This device will be not be used anymore. The device context must not be used by the server too. + * + * @param hServer The VRDE server instance. + * @param pDeviceHandle The device reported by ATTACH notification. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInDeviceDetach, (HVRDESERVER hServer, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle)); + + /* Get a device description. + * + * @param hServer The VRDE server instance. + * @param pvUser The callers context of this request. + * @param pDeviceHandle The device reported by ATTACH notification. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInGetDeviceDesc, (HVRDESERVER hServer, + void *pvUser, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle)); + + /* Submit a set/get control request. + * + * @param hServer The VRDE server instance. + * @param pvUser The callers context of this request. + * @param pDeviceHandle The device reported by ATTACH notification. + * @param pReq The request. + * @param cbReq Size of the request. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInControl, (HVRDESERVER hServer, + void *pvUser, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, + const VRDEVIDEOINCTRLHDR *pReq, + uint32_t cbReq)); + +} VRDEVIDEOININTERFACE; + + +/* + * Notifications. + * Data structures: pvData of VRDEVIDEOINCALLBACKS::VRDECallbackVideoInNotify. + */ +typedef struct VRDEVIDEOINNOTIFYATTACH +{ + VRDEVIDEOINDEVICEHANDLE deviceHandle; + uint32_t u32Version; /* VRDE_VIDEOIN_NEGOTIATE_VERSION */ + uint32_t fu32Capabilities; /* VRDE_VIDEOIN_NEGOTIATE_CAP_* */ +} VRDEVIDEOINNOTIFYATTACH; + +typedef struct VRDEVIDEOINNOTIFYDETACH +{ + VRDEVIDEOINDEVICEHANDLE deviceHandle; +} VRDEVIDEOINNOTIFYDETACH; + +/* Notification codes, */ +#define VRDE_VIDEOIN_NOTIFY_ID_ATTACH 0 +#define VRDE_VIDEOIN_NOTIFY_ID_DETACH 1 + + +/* Video input interface callbacks. */ +typedef struct VRDEVIDEOINCALLBACKS +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* Notifications. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param u32EventId The notification identifier: VRDE_VIDEOIN_NOTIFY_*. + * @param pvData The notification specific data. + * @param cbData The size of buffer pointed by pvData. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInNotify,(void *pvCallback, + uint32_t u32Id, + const void *pvData, + uint32_t cbData)); + + /* Device description received from the client. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcRequest The result code of the request. + * @param pDeviceCtx The device context associated with the device in VRDEVideoInGetDeviceDesc. + * @param pvUser The pvUser parameter of VRDEVideoInGetDeviceDesc. + * @param pDeviceDesc The device description. + * @param cbDeviceDesc The size of buffer pointed by pDevice. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInDeviceDesc,(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + void *pvUser, + const VRDEVIDEOINDEVICEDESC *pDeviceDesc, + uint32_t cbDeviceDesc)); + + /* Control response or notification. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcRequest The result code of the request. + * @param pDeviceCtx The device context associated with the device in VRDEVideoInGetDeviceDesc. + * @param pvUser The pvUser parameter of VRDEVideoInControl. NULL if this is a notification. + * @param pControl The control information. + * @param cbControl The size of buffer pointed by pControl. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInControl,(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + void *pvUser, + const VRDEVIDEOINCTRLHDR *pControl, + uint32_t cbControl)); + + /* Frame which was received from the client. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcRequest The result code of the request. + * @param pDeviceCtx The device context associated with the device in VRDEVideoInGetDeviceDesc. + * @param pFrame The frame data. + * @param cbFrame The size of buffer pointed by pFrame. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInFrame,(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + const VRDEVIDEOINPAYLOADHDR *pFrame, + uint32_t cbFrame)); + +} VRDEVIDEOINCALLBACKS; +#endif /* VRDE_VIDEOIN_WITH_VRDEINTERFACE */ + +#pragma pack() + +#endif diff --git a/include/VBox/VBoxCrHgsmi.h b/include/VBox/VBoxCrHgsmi.h index 9d25a5df..e79a5c1f 100644 --- a/include/VBox/VBoxCrHgsmi.h +++ b/include/VBox/VBoxCrHgsmi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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/include/VBox/VBoxDrvCfg-win.h b/include/VBox/VBoxDrvCfg-win.h index ac8092a4..abca190f 100644 --- a/include/VBox/VBoxDrvCfg-win.h +++ b/include/VBox/VBoxDrvCfg-win.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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/include/VBox/VBoxGL2D.h b/include/VBox/VBoxGL2D.h index ab0f99db..a29c2726 100644 --- a/include/VBox/VBoxGL2D.h +++ b/include/VBox/VBoxGL2D.h @@ -5,7 +5,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/include/VBox/VBoxGuest.h b/include/VBox/VBoxGuest.h index d23e5a2d..62dfe1f9 100644 --- a/include/VBox/VBoxGuest.h +++ b/include/VBox/VBoxGuest.h @@ -5,7 +5,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; @@ -61,6 +61,9 @@ /** Device name. */ # define VBOXGUEST_DEVICE_NAME_DOS L"\\DosDevices\\VBoxGuest" +#elif defined(RT_OS_HAIKU) +# define VBOXGUEST_DEVICE_NAME "/dev/misc/vboxguest" + #else /* (PORTME) */ # define VBOXGUEST_DEVICE_NAME "/dev/vboxguest" # if defined(RT_OS_LINUX) @@ -146,7 +149,7 @@ typedef const VBGLBIGREQ *PCVBGLBIGREQ; #if defined(RT_OS_WINDOWS) -/* @todo Remove IOCTL_CODE later! Integrate it in VBOXGUEST_IOCTL_CODE below. */ +/** @todo Remove IOCTL_CODE later! Integrate it in VBOXGUEST_IOCTL_CODE below. */ /** @todo r=bird: IOCTL_CODE is supposedly defined in some header included by Windows.h or ntddk.h, which is why it wasn't in the #if 0 earlier. See HostDrivers/Support/SUPDrvIOC.h... */ # define IOCTL_CODE(DeviceType, Function, Method, Access, DataSize_ignored) \ ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) @@ -175,6 +178,13 @@ typedef const VBGLBIGREQ *PCVBGLBIGREQ; # define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO( 'V', (Function)) # define VBOXGUEST_IOCTL_STRIP_SIZE(Code) VBOXGUEST_IOCTL_CODE_(_IOC_NR((Code)), 0) +#elif defined(RT_OS_HAIKU) + /* No automatic buffering, size not encoded. */ + /** @todo do something better */ +# define VBOXGUEST_IOCTL_CODE_(Function, Size) (0x56420000 | (Function)) +# define VBOXGUEST_IOCTL_CODE_FAST_(Function) (0x56420000 | (Function)) +# define VBOXGUEST_IOCTL_STRIP_SIZE(Code) (Code) + #elif defined(RT_OS_FREEBSD) /** @todo r=bird: Please do it like SUPDRVIOC to keep it as similar as possible. */ # include @@ -185,8 +195,8 @@ typedef const VBGLBIGREQ *PCVBGLBIGREQ; #else /* BSD Like */ /* Automatic buffering, size limited to 4KB on *BSD and 8KB on Darwin - commands the limit, 4KB. */ # include -# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOC(IOC_INOUT, 'V', (Function) | VBOXGUEST_IOCTL_FLAG, (Size)) -# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO('V', (Function) | VBOXGUEST_IOCTL_FLAG) +# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOC(IOC_INOUT, 'V', (Function), (Size)) +# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO('V', (Function)) # define VBOXGUEST_IOCTL_STRIP_SIZE(uIOCtl) ( (uIOCtl) & ~_IOC(0,0,0,IOCPARM_MASK) ) #endif @@ -321,7 +331,7 @@ typedef struct VBoxGuestWriteCoreDump AssertCompileSize(VBoxGuestWriteCoreDump, 4); /** IOCTL to VBoxGuest to update the mouse status features. */ -# define VBOXGUEST_IOCTL_SET_MOUSE_STATUS VBOXGUEST_IOCTL_CODE_(10, sizeof(uint32_t)) +# define VBOXGUEST_IOCTL_SET_MOUSE_STATUS VBOXGUEST_IOCTL_CODE_(10, sizeof(uint32_t)) #ifdef VBOX_WITH_HGCM /** IOCTL to VBoxGuest to connect to a HGCM service. */ @@ -340,7 +350,7 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4); /** IOCTL to VBoxGuest passed from the Kernel Mode driver, but containing a user mode data in VBoxGuestHGCMCallInfo * the driver received from the UM. Called in the context of the process passing the data. * @see VBoxGuestHGCMCallInfo */ -# define VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(Size) VBOXGUEST_IOCTL_CODE(21, (Size)) +# define VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(Size) VBOXGUEST_IOCTL_CODE(21, (Size)) # ifdef RT_ARCH_AMD64 /** @name IOCTL numbers that 32-bit clients, like the Windows OpenGL guest @@ -353,10 +363,6 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4); /** @} */ # endif /* RT_ARCH_AMD64 */ -#ifdef VBOX_WITH_DPC_LATENCY_CHECKER -#define VBOXGUEST_IOCTL_DPC VBOXGUEST_IOCTL_CODE(30, 0) -#endif - /** Get the pointer to the first HGCM parameter. */ # define VBOXGUEST_HGCM_CALL_PARMS(a) ( (HGCMFunctionParameter *)((uint8_t *)(a) + sizeof(VBoxGuestHGCMCallInfo)) ) /** Get the pointer to the first HGCM parameter in a 32-bit request. */ @@ -364,8 +370,56 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4); #endif /* VBOX_WITH_HGCM */ -/** IOCTL to for setting the mouse driver callback. (kernel only) */ -#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK VBOXGUEST_IOCTL_CODE_(31, sizeof(VBoxGuestMouseSetNotifyCallback)) +#ifdef VBOX_WITH_DPC_LATENCY_CHECKER +/** IOCTL to VBoxGuest to perform DPC latency tests, printing the result in + * the release log on the host. Takes no data, returns no data. */ +# define VBOXGUEST_IOCTL_DPC_LATENCY_CHECKER VBOXGUEST_IOCTL_CODE_(30, 0) +#endif + +/** IOCTL to for setting the mouse driver callback. (kernel only) */ +#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK VBOXGUEST_IOCTL_CODE(31, sizeof(VBoxGuestMouseSetNotifyCallback)) + +typedef enum VBOXGUESTCAPSACQUIRE_FLAGS +{ + VBOXGUESTCAPSACQUIRE_FLAGS_NONE = 0, + /* configures VBoxGuest to use the specified caps in Acquire mode, w/o making any caps acquisition/release. + * so far it is only possible to set acquire mode for caps, but not clear it, + * so u32NotMask is ignored for this request */ + VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE, + /* to ensure enum is 32bit*/ + VBOXGUESTCAPSACQUIRE_FLAGS_32bit = 0x7fffffff +} VBOXGUESTCAPSACQUIRE_FLAGS; + +typedef struct VBoxGuestCapsAquire +{ + /* result status + * VINF_SUCCESS - on success + * VERR_RESOURCE_BUSY - some caps in the u32OrMask are acquired by some other VBoxGuest connection. + * NOTE: no u32NotMask caps are cleaned in this case, i.e. no modifications are done on failure + * VER_INVALID_PARAMETER - invalid Caps are specified with either u32OrMask or u32NotMask. No modifications are done on failure. + */ + int32_t rc; + /* Acquire command */ + VBOXGUESTCAPSACQUIRE_FLAGS enmFlags; + /* caps to acquire, OR-ed VMMDEV_GUEST_SUPPORTS_XXX flags */ + uint32_t u32OrMask; + /* caps to release, OR-ed VMMDEV_GUEST_SUPPORTS_XXX flags */ + uint32_t u32NotMask; +} VBoxGuestCapsAquire; + +/** IOCTL to for Acquiring/Releasing Guest Caps + * This is used for multiple purposes: + * 1. By doing Acquire r3 client application (e.g. VBoxTray) claims it will use + * the given connection for performing operations like Seamles or Auto-resize, + * thus, if the application terminates, the driver will automatically cleanup the caps reported to host, + * so that host knows guest does not support them anymore + * 2. In a multy-user environment this will not allow r3 applications (like VBoxTray) + * running in different user sessions simultaneously to interfere with each other. + * An r3 client application (like VBoxTray) is responsible for Acquiring/Releasing caps properly as needed. + **/ +#define VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE VBOXGUEST_IOCTL_CODE(32, sizeof(VBoxGuestCapsAquire)) + + typedef DECLCALLBACK(void) FNVBOXGUESTMOUSENOTIFY(void *pfnUser); typedef FNVBOXGUESTMOUSENOTIFY *PFNVBOXGUESTMOUSENOTIFY; diff --git a/include/VBox/VBoxGuest.inc b/include/VBox/VBoxGuest.inc index 87982549..321f8f8f 100644 --- a/include/VBox/VBoxGuest.inc +++ b/include/VBox/VBoxGuest.inc @@ -3,7 +3,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/include/VBox/VBoxGuest.mac b/include/VBox/VBoxGuest.mac index 9d0cd6a1..0da8aa17 100644 --- a/include/VBox/VBoxGuest.mac +++ b/include/VBox/VBoxGuest.mac @@ -3,7 +3,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/include/VBox/VBoxGuest16.h b/include/VBox/VBoxGuest16.h index 15aa986c..0a431278 100644 --- a/include/VBox/VBoxGuest16.h +++ b/include/VBox/VBoxGuest16.h @@ -3,7 +3,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/include/VBox/VBoxGuest2.h b/include/VBox/VBoxGuest2.h index 4e17b2df..05344c32 100644 --- a/include/VBox/VBoxGuest2.h +++ b/include/VBox/VBoxGuest2.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 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/include/VBox/VBoxGuestLib.h b/include/VBox/VBoxGuestLib.h index c860a073..dea1a6a0 100644 --- a/include/VBox/VBoxGuestLib.h +++ b/include/VBox/VBoxGuestLib.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -86,7 +86,11 @@ RT_C_DECLS_BEGIN /** @def DECLR0VBGL * Declare a VBGL ring-0 API with the right calling convention and visibilitiy. * @param type Return type. */ -# define DECLR0VBGL(type) type VBOXCALL +# ifdef RT_OS_DARWIN /** @todo probably apply to all, but don't want a forest fire on our hands right now. */ +# define DECLR0VBGL(type) DECLHIDDEN(type) VBOXCALL +# else +# define DECLR0VBGL(type) type VBOXCALL +# endif # define DECLVBGL(type) DECLR0VBGL(type) typedef uint32_t VBGLIOPORT; /**< @todo r=bird: We have RTIOPORT (uint16_t) for this. */ @@ -178,7 +182,7 @@ DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq); * @param pvData VBoxGuest pointer to be passed to callback. * @param u32Data VBoxGuest 32 bit value to be passed to callback. */ -typedef DECLVBGL(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data); +typedef DECLCALLBACK(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data); /** Pointer to a FNVBGLHGCMCALLBACK. */ typedef FNVBGLHGCMCALLBACK *PFNVBGLHGCMCALLBACK; @@ -379,9 +383,9 @@ DECLVBGL(void *) VbglPhysHeapAlloc (uint32_t cbSize); * * * @param p Virtual address of memory block. - * @return Physical memory block. + * @return Physical address of the memory block. */ -DECLVBGL(RTCCPHYS) VbglPhysHeapGetPhysAddr (void *p); +DECLVBGL(uint32_t) VbglPhysHeapGetPhysAddr (void *p); /** * Free a memory block. @@ -477,6 +481,9 @@ VBGLR3DECL(int) VbglR3SetPointerShapeReq(struct VMMDevReqMousePointer *pReq) /** @name Display * @{ */ VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, uint32_t *piDisplay, bool fAck); +VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, + uint32_t *piDisplay, uint32_t *pcOriginX, uint32_t *pcOriginY, + bool *pfEnabled, bool fAck); VBGLR3DECL(bool) VbglR3HostLikesVideoMode(uint32_t cx, uint32_t cy, uint32_t cBits); VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t cy, uint32_t cBits); VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits); @@ -523,10 +530,16 @@ VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId, char const * const VBGLR3DECL(int) VbglR3GuestPropEnumNext(PVBGLR3GUESTPROPENUM pHandle, char const **ppszName, char const **ppszValue, uint64_t *pu64Timestamp, char const **ppszFlags); VBGLR3DECL(void) VbglR3GuestPropEnumFree(PVBGLR3GUESTPROPENUM pHandle); +VBGLR3DECL(int) VbglR3GuestPropDelete(uint32_t u32ClientId, const char *pszName); VBGLR3DECL(int) VbglR3GuestPropDelSet(uint32_t u32ClientId, char const * const *papszPatterns, uint32_t cPatterns); VBGLR3DECL(int) VbglR3GuestPropWait(uint32_t u32ClientId, const char *pszPatterns, void *pvBuf, uint32_t cbBuf, uint64_t u64Timestamp, uint32_t cMillies, char ** ppszName, char **ppszValue, uint64_t *pu64Timestamp, char **ppszFlags, uint32_t *pcbBufActual); /** @} */ +/** @name Guest user handling / reporting. + * @{ */ +VBGLR3DECL(int) VbglR3GuestUserReportState(const char *pszUser, const char *pszDomain, VBoxGuestUserState enmState, uint8_t *puDetails, uint32_t cbDetails); +/** @} */ + /** @name Host version handling * @{ */ VBGLR3DECL(int) VbglR3HostVersionCheckForUpdate(uint32_t u32ClientId, bool *pfUpdate, char **ppszHostVersion, char **ppszGuestVersion); @@ -566,78 +579,79 @@ VBGLR3DECL(int) VbglR3SharedFolderGetMountDir(char **ppszDir); # ifdef VBOX_WITH_GUEST_CONTROL /** @name Guest control * @{ */ -/** @todo Clean this up, uniform formatting. */ -VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu32ClientId); -VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId); -VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms); -VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId); -/* Process execution. */ -VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdExec(uint32_t u32ClientId, uint32_t cParms, - uint32_t *puContext, - char *pszCmd, uint32_t cbCmd, - uint32_t *puFlags, - char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs, - char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars, - char *pszUser, uint32_t cbUser, - char *pszPassword, uint32_t cbPassword, - uint32_t *puTimeLimit); -VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t uNumParms, - uint32_t *puContext, uint32_t *puPID, - uint32_t *puFlags, void *pvData, - uint32_t cbData, uint32_t *pcbSize); -VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t uNumParms, - uint32_t *puContext, uint32_t *puPID, - uint32_t *puHandle, uint32_t *puFlags); -VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t u32ClientId, - uint32_t u32Context, - uint32_t u32PID, - uint32_t u32Status, - uint32_t u32Flags, - void *pvData, - uint32_t cbData); -VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t u32ClientId, - uint32_t u32Context, - uint32_t u32PID, - uint32_t u32Handle, - uint32_t u32Flags, - void *pvData, - uint32_t cbData); -VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatusIn(uint32_t u32ClientId, - uint32_t u32Context, - uint32_t u32PID, - uint32_t u32Status, - uint32_t u32Flags, - uint32_t cbWritten); -/* Native file handling. */ -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdOpen(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - char *pszFileName, uint32_t cbFileName, - char *pszOpenMode, uint32_t cbOpenMode, - char *pszDisposition, uint32_t cbDisposition, - uint32_t *puCreationMode, - uint64_t *puOffset); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdClose(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdRead(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle, uint32_t *puToRead); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdWrite(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle, - void *pvData, uint32_t cbData, - uint32_t *pcbSize); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdSeek(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle, - uint32_t *puSeekMethod, uint64_t *puOffset); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdTell(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle); -VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t uClientId, - uint32_t uContext, uint32_t uHandle, - uint32_t uType, - void *pvPayload, uint32_t cbPayload); + +/** + * Structure containing the context required for + * either retrieving or sending a HGCM guest control + * command from or to the host. + * + * Note: Do not change parameter order without also + * adapting all structure initializers. + */ +typedef struct VBGLR3GUESTCTRLCMDCTX +{ + /** @todo This struct could be handy if we want to implement + * a second communication channel, e.g. via TCP/IP. + * Use a union for the HGCM stuff then. */ + + /** IN: HGCM client ID to use for + * communication. */ + uint32_t uClientID; + /** IN/OUT: Context ID to retrieve + * or to use. */ + uint32_t uContextID; + /** IN: Protocol version to use. */ + uint32_t uProtocol; + /** OUT: Number of parameters retrieved. */ + uint32_t uNumParms; +} VBGLR3GUESTCTRLCMDCTX, *PVBGLR3GUESTCTRLCMDCTX; + +/* General message handling on the guest. */ +VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *puClientId); +VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t uClientId); +VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t uClientId, uint32_t uValue, uint32_t uMaskAdd, uint32_t uMaskRemove); +VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterUnset(uint32_t uClientId); +VBGLR3DECL(int) VbglR3GuestCtrlMsgReply(PVBGLR3GUESTCTRLCMDCTX pCtx, int rc); +VBGLR3DECL(int) VbglR3GuestCtrlMsgReplyEx(PVBGLR3GUESTCTRLCMDCTX pCtx, int rc, uint32_t uType, void *pvPayload, uint32_t cbPayload); +VBGLR3DECL(int) VbglR3GuestCtrlMsgSkip(uint32_t uClientId); +VBGLR3DECL(int) VbglR3GuestCtrlMsgWaitFor(uint32_t uClientId, uint32_t *puMsg, uint32_t *puNumParms); +VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId); +/* Guest session handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uFlags); +VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, uint32_t uResult); +VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puProtocol, char *pszUser, uint32_t cbUser, char *pszPassword, uint32_t cbPassword, char *pszDomain, uint32_t cbDomain, uint32_t *puFlags, uint32_t *puSessionID); +VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puFlags, uint32_t *puSessionID); +/* Guest path handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszSource, uint32_t cbSource, char *pszDest, uint32_t cbDest, uint32_t *puFlags); +/* Guest process execution. */ +VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszCmd, uint32_t cbCmd, uint32_t *puFlags, char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs, char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars, char *pszUser, uint32_t cbUser, char *pszPassword, uint32_t cbPassword, uint32_t *puTimeoutMS, uint32_t *puPriority, uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puFlags, void *pvData, uint32_t cbData, uint32_t *pcbSize); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puHandle, uint32_t *puFlags); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS); +/* Guest native directory handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *puFlags); +/* Guest native file handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszFileName, uint32_t cbFileName, char *pszOpenMode, uint32_t cbOpenMode, char *pszDisposition, uint32_t cbDisposition, char *pszSharing, uint32_t cbSharing, uint32_t *puCreationMode, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, void *pvData, uint32_t cbData, uint32_t *pcbSize); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle); +/* Guest -> Host. */ +VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uFileHandle); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, void *pvData, uint32_t cbData); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uWritten); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t uOffActual); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t uOffActual); +VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uStatus, uint32_t uFlags, void *pvData, uint32_t cbData); +VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData); +VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t u32PID, uint32_t uStatus, uint32_t uFlags, uint32_t cbWritten); + /** @} */ # endif /* VBOX_WITH_GUEST_CONTROL defined */ diff --git a/include/VBox/VBoxNetCfg-win.h b/include/VBox/VBoxNetCfg-win.h index 8e327c0d..8dcaa0a4 100644 --- a/include/VBox/VBoxNetCfg-win.h +++ b/include/VBox/VBoxNetCfg-win.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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/include/VBox/VBoxTpG.h b/include/VBox/VBoxTpG.h index 260ee6f2..4d23dd34 100644 --- a/include/VBox/VBoxTpG.h +++ b/include/VBox/VBoxTpG.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2012 Oracle Corporation + * Copyright (C) 2012-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; @@ -122,8 +122,18 @@ typedef VTGPROBELOC const *PCVTGPROBELOC; # error "Unsupported Darwin compiler!" # endif -#elif defined(RT_OS_OS2) -# error "OS/2 is not supported" +#elif defined(RT_OS_OS2) /** @todo This doesn't actually work, but it makes the code compile. */ +# define VTG_OBJ_SECT "__DATA" +# define VTG_LOC_SECT "__VTGPrLc" +# define VTG_LOC_SET "__VTGPrLcSet" +# ifdef __GNUC__ +# define VTG_DECL_VTGPROBELOC(a_VarName) \ + static VTGPROBELOC a_VarName; \ + __asm__ (".stabs \"__VTGPrLcSet\", 23, 0, 0, _" #a_VarName ); + +# else +# error "Unsupported Darwin compiler!" +# endif #else /* Assume the rest uses ELF. */ # define VTG_OBJ_SECT ".VTGObj" diff --git a/include/VBox/VBoxUhgsmi.h b/include/VBox/VBoxUhgsmi.h index 459c6352..eed8345d 100644 --- a/include/VBox/VBoxUhgsmi.h +++ b/include/VBox/VBoxUhgsmi.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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/include/VBox/VBoxVideo.h b/include/VBox/VBoxVideo.h index bbc6d7b5..9d499e53 100644 --- a/include/VBox/VBoxVideo.h +++ b/include/VBox/VBoxVideo.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006 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; @@ -852,6 +852,9 @@ typedef struct VBVABUFFER #define VBVA_INFO_CAPS 12 /* informs host about HGSMI caps. see VBVACAPS below */ #define VBVA_SCANLINE_CFG 13 /* configures scanline, see VBVASCANLINECFG below */ #define VBVA_SCANLINE_INFO 14 /* requests scanline info, see VBVASCANLINEINFO below */ +#define VBVA_CMDVBVA_SUBMIT 16 /* inform host about VBVA Command submission */ +#define VBVA_CMDVBVA_FLUSH 17 /* inform host about VBVA Command submission */ +#define VBVA_CMDVBVA_CTL 18 /* G->H DMA command */ /* host->guest commands */ #define VBVAHG_EVENT 1 @@ -945,6 +948,20 @@ typedef struct VBVAFLUSH } VBVAFLUSH; +typedef struct VBVACMDVBVASUBMIT +{ + uint32_t u32Reserved; +} VBVACMDVBVASUBMIT; + +/* flush is requested because due to guest command buffer overflow */ +#define VBVACMDVBVAFLUSH_F_GUEST_BUFFER_OVERFLOW 1 + +typedef struct VBVACMDVBVAFLUSH +{ + uint32_t u32Flags; +} VBVACMDVBVAFLUSH; + + /* VBVAINFOSCREEN::u8Flags */ #define VBVA_SCREEN_F_NONE 0x0000 #define VBVA_SCREEN_F_ACTIVE 0x0001 @@ -1397,8 +1414,7 @@ typedef struct VBOXVDMACMD_CHILD_STATUS_IRQ # pragma pack() #endif /* #ifdef VBOX_WITH_VDMA */ -#ifdef VBOX_WITH_CRHGSMI -# pragma pack(1) +#pragma pack(1) typedef struct VBOXVDMACMD_CHROMIUM_BUFFER { VBOXVIDEOOFFSET offBuffer; @@ -1420,8 +1436,9 @@ typedef enum VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP, VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN, VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END, - VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION, - VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0xfffffffe + VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB, + VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRCONNECT, + VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0x7fffffff } VBOXVDMACMD_CHROMIUM_CTL_TYPE; typedef struct VBOXVDMACMD_CHROMIUM_CTL @@ -1430,29 +1447,333 @@ typedef struct VBOXVDMACMD_CHROMIUM_CTL uint32_t cbCmd; } VBOXVDMACMD_CHROMIUM_CTL, *PVBOXVDMACMD_CHROMIUM_CTL; -typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP -{ - VBOXVDMACMD_CHROMIUM_CTL Hdr; - union - { - void *pvVRamBase; - uint64_t uAlignment; - }; - uint64_t cbVRam; -} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP; typedef struct PDMIDISPLAYVBVACALLBACKS *HCRHGSMICMDCOMPLETION; typedef DECLCALLBACK(int) FNCRHGSMICMDCOMPLETION(HCRHGSMICMDCOMPLETION hCompletion, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc); typedef FNCRHGSMICMDCOMPLETION *PFNCRHGSMICMDCOMPLETION; -typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION +typedef DECLCALLBACK(bool) FNCROGLHASDATA(void); +typedef FNCROGLHASDATA *PFNCROGLHASDATA; + +/* callbacks chrogl gives to main */ +typedef struct CR_MAIN_INTERFACE +{ + PFNCROGLHASDATA pfnHasData; +} CR_MAIN_INTERFACE; + +typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB { VBOXVDMACMD_CHROMIUM_CTL Hdr; + /*in*/ HCRHGSMICMDCOMPLETION hCompletion; PFNCRHGSMICMDCOMPLETION pfnCompletion; -} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION; -# pragma pack() -#endif + /*out*/ + CR_MAIN_INTERFACE MainInterface; +} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB; + +typedef struct VBOXCRCON_SERVER *HVBOXCRCON_SERVER; +typedef struct PDMIDISPLAYVBVACALLBACKS* HVBOXCRCON_CLIENT; + +typedef struct VBOXCRCON_3DRGN_CLIENT* HVBOXCRCON_3DRGN_CLIENT; +typedef struct VBOXCRCON_3DRGN_ASYNCCLIENT* HVBOXCRCON_3DRGN_ASYNCCLIENT; + +/* server callbacks */ +/* submit chromium cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_CRCMD(HVBOXCRCON_SERVER hServer, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd); +typedef FNVBOXCRCON_SVR_CRCMD *PFNVBOXCRCON_SVR_CRCMD; + +/* submit chromium control cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_CRCTL(HVBOXCRCON_SERVER hServer, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCmd); +typedef FNVBOXCRCON_SVR_CRCTL *PFNVBOXCRCON_SVR_CRCTL; + +/* request 3D data. + * The protocol is the following: + * 1. if there is no 3D data displayed on screen, returns VINF_EOF immediately w/o calling any PFNVBOXCRCON_3DRGN_XXX callbacks + * 2. otherwise calls PFNVBOXCRCON_3DRGN_ONSUBMIT, submits the "regions get" request to the CrOpenGL server to process it asynchronously and returns VINF_SUCCESS + * 2.a on "regions get" request processing calls PFNVBOXCRCON_3DRGN_BEGIN, + * 2.b then PFNVBOXCRCON_3DRGN_REPORT zero or more times for each 3D region, + * 2.c and then PFNVBOXCRCON_3DRGN_END + * 3. returns VERR_XXX code on failure + * */ +typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_3DRGN_GET(HVBOXCRCON_SERVER hServer, HVBOXCRCON_3DRGN_CLIENT hRgnClient, uint32_t idScreen); +typedef FNVBOXCRCON_SVR_3DRGN_GET *PFNVBOXCRCON_SVR_3DRGN_GET; + +/* 3D Regions Client callbacks */ +/* called from the PFNVBOXCRCON_SVR_3DRGN_GET callback in case server has 3D data and is going to process the request asynchronously, + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_ONSUBMIT(HVBOXCRCON_3DRGN_CLIENT hRgnClient, uint32_t idScreen, HVBOXCRCON_3DRGN_ASYNCCLIENT *phRgnAsyncClient); +typedef FNVBOXCRCON_3DRGN_ONSUBMIT *PFNVBOXCRCON_3DRGN_ONSUBMIT; + +/* called from the "regions get" command processing thread, to indicate that the "regions get" is started. + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_BEGIN(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen); +typedef FNVBOXCRCON_3DRGN_BEGIN *PFNVBOXCRCON_3DRGN_BEGIN; + +/* called from the "regions get" command processing thread, to report a 3D region. + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_REPORT(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen, void *pvData, uint32_t cbStride, const RTRECT *pRect); +typedef FNVBOXCRCON_3DRGN_REPORT *PFNVBOXCRCON_3DRGN_REPORT; + +/* called from the "regions get" command processing thread, to indicate that the "regions get" is completed. + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_END(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen); +typedef FNVBOXCRCON_3DRGN_END *PFNVBOXCRCON_3DRGN_END; + + +/* client callbacks */ +/* complete chromium cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_CLT_CRCTL_COMPLETE(HVBOXCRCON_CLIENT hClient, PVBOXVDMACMD_CHROMIUM_CTL pCtl, int rc); +typedef FNVBOXCRCON_CLT_CRCTL_COMPLETE *PFNVBOXCRCON_CLT_CRCTL_COMPLETE; + +/* complete chromium control cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_CLT_CRCMD_COMPLETE(HVBOXCRCON_CLIENT hClient, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc); +typedef FNVBOXCRCON_CLT_CRCMD_COMPLETE *PFNVBOXCRCON_CLT_CRCMD_COMPLETE; + +typedef struct VBOXCRCON_SERVER_CALLBACKS +{ + HVBOXCRCON_SERVER hServer; + PFNVBOXCRCON_SVR_CRCMD pfnCrCmd; + PFNVBOXCRCON_SVR_CRCTL pfnCrCtl; + PFNVBOXCRCON_SVR_3DRGN_GET pfn3DRgnGet; +} VBOXCRCON_SERVER_CALLBACKS, *PVBOXCRCON_SERVER_CALLBACKS; + +typedef struct VBOXCRCON_CLIENT_CALLBACKS +{ + HVBOXCRCON_CLIENT hClient; + PFNVBOXCRCON_CLT_CRCMD_COMPLETE pfnCrCmdComplete; + PFNVBOXCRCON_CLT_CRCTL_COMPLETE pfnCrCtlComplete; + PFNVBOXCRCON_3DRGN_ONSUBMIT pfn3DRgnOnSubmit; + PFNVBOXCRCON_3DRGN_BEGIN pfn3DRgnBegin; + PFNVBOXCRCON_3DRGN_REPORT pfn3DRgnReport; + PFNVBOXCRCON_3DRGN_END pfn3DRgnEnd; +} VBOXCRCON_CLIENT_CALLBACKS, *PVBOXCRCON_CLIENT_CALLBACKS; + +/* issued by Main to establish connection between Main and CrOpenGL service */ +typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRCONNECT +{ + VBOXVDMACMD_CHROMIUM_CTL Hdr; + /*input (filled by Client) :*/ + /*class VMMDev*/void *pVMMDev; + VBOXCRCON_CLIENT_CALLBACKS ClientCallbacks; + /*output (filled by Server) :*/ + VBOXCRCON_SERVER_CALLBACKS ServerCallbacks; +} VBOXVDMACMD_CHROMIUM_CTL_CRCONNECT, *PVBOXVDMACMD_CHROMIUM_CTL_CRCONNECT; + +/* ring command buffer dr */ +#define VBOXCMDVBVA_STATE_SUBMITTED 1 +#define VBOXCMDVBVA_STATE_CANCELLED 2 +#define VBOXCMDVBVA_STATE_IN_PROGRESS 3 +/* the "completed" state is signalled via the ring buffer values */ + +/* CrHgsmi command */ +#define VBOXCMDVBVA_OPTYPE_CRCMD 1 +/* blit command that does blitting of allocations identified by VRAM offset or host id + * for VRAM-offset ones the size and format are same as primary */ +#define VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID 2 +/* flip */ +#define VBOXCMDVBVA_OPTYPE_FLIP 3 +/* ColorFill */ +#define VBOXCMDVBVA_OPTYPE_CLRFILL 4 +/* allocation paging transfer request */ +#define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER 5 +/* allocation paging fill request */ +#define VBOXCMDVBVA_OPTYPE_PAGING_FILL 6 +/* same as VBOXCMDVBVA_OPTYPE_NOP, but contains VBOXCMDVBVA_HDR data */ +#define VBOXCMDVBVA_OPTYPE_NOPCMD 7 + +/* nop - is a one-bit command. The buffer size to skip is determined by VBVA buffer size */ +#define VBOXCMDVBVA_OPTYPE_NOP 0x80 + +/* u8Flags flags */ +/* source allocation is specified with the host id. if not set - source allocation is specified with VRAM offset */ +#define VBOXCMDVBVA_OPF_ALLOC_SRCID 0x80 +/* destination allocation is specified with the host id. if not set - destination allocation is specified with VRAM offset */ +#define VBOXCMDVBVA_OPF_ALLOC_DSTID 0x40 + +/* transfer from RAM to Allocation */ +#define VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN 0x20 + +/* VBOXCMDVBVA_OPTYPE_BLT_PRIMARY specific flags*/ +/* if set - src is a primary id */ +#define VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY 0x20 +/* if set - dst is a primary id */ +#define VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY 0x10 + + +/* trying to make the header as small as possible, + * we'd have pretty few op codes actually, so 8bit is quite enough, + * we will be able to extend it in any way. */ +typedef struct VBOXCMDVBVA_HDR +{ + /* one VBOXCMDVBVA_OPTYPE_XXX, except NOP, see comments above */ + uint8_t u8OpCode; + /* command-specific + * VBOXCMDVBVA_OPTYPE_CRCMD - must be null + * VBOXCMDVBVA_OPTYPE_BLT_PRIMARY - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags + * VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags + * VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER - must be null + * VBOXCMDVBVA_OPTYPE_PAGING_FILL - must be null + * VBOXCMDVBVA_OPTYPE_NOPCMD - must be null + * VBOXCMDVBVA_OPTYPE_NOP - not applicable (as the entire VBOXCMDVBVA_HDR is not valid) */ + uint8_t u8Flags; + /* one of VBOXCMDVBVA_STATE_XXX*/ + volatile uint8_t u8State; + union + { + /* result, 0 on success, otherwise contains the failure code TBD */ + int8_t i8Result; + uint8_t u8PrimaryID; + } u; + /* DXGK DDI fence ID */ + volatile uint32_t u32FenceID; +} VBOXCMDVBVA_HDR; + +typedef uint32_t VBOXCMDVBVAOFFSET; +typedef uint64_t VBOXCMDVBVAPHADDR; + +typedef struct VBOXCMDVBVA_CRCMD_BUFFER +{ + uint32_t cbBuffer; + VBOXCMDVBVAOFFSET offBuffer; +} VBOXCMDVBVA_CRCMD_BUFFER; + +typedef struct VBOXCMDVBVA_CRCMD_CMD +{ + uint32_t cBuffers; + VBOXCMDVBVA_CRCMD_BUFFER aBuffers[1]; +} VBOXCMDVBVA_CRCMD_CMD; + +typedef struct VBOXCMDVBVA_CRCMD +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_CRCMD_CMD Cmd; +} VBOXCMDVBVA_CRCMD; + +typedef struct VBOXCMDVBVA_ALLOCINFO +{ + union + { + VBOXCMDVBVAOFFSET offVRAM; + uint32_t id; + } u; +} VBOXCMDVBVA_ALLOCINFO; + +typedef struct VBOXCMDVBVA_RECT +{ + /** Coordinates of affected rectangle. */ + int16_t xLeft; + int16_t yTop; + int16_t xRight; + int16_t yBottom; +} VBOXCMDVBVA_RECT; + +typedef struct VBOXCMDVBVA_POINT +{ + int16_t x; + int16_t y; +} VBOXCMDVBVA_POINT; + +typedef struct VBOXCMDVBVA_BLT_PRIMARY +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO alloc; + VBOXCMDVBVA_POINT Pos; + /* the rects count is determined from the command size */ + VBOXCMDVBVA_RECT aRects[1]; +} VBOXCMDVBVA_BLT_PRIMARY; + +typedef struct VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO src; + VBOXCMDVBVA_ALLOCINFO dst; + VBOXCMDVBVA_POINT Pos; + /* the rects count is determined from the command size */ + VBOXCMDVBVA_RECT aRects[1]; +} VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID; + +typedef struct VBOXCMDVBVA_FLIP +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO src; +} VBOXCMDVBVA_FLIP; + +typedef struct VBOXCMDVBVA_CLRFILL +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO dst; + VBOXCMDVBVA_RECT aRects[1]; +} VBOXCMDVBVA_CLRFILL; + +#define VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX 0x1000 + +typedef struct VBOXCMDVBVA_SYSMEMEL +{ + uint32_t cPagesAfterFirst : 12; + uint32_t iPage1 : 20; + uint32_t iPage2; +} VBOXCMDVBVA_SYSMEMEL; + +typedef struct VBOXCMDVBVA_PAGING_TRANSFER +{ + VBOXCMDVBVA_HDR Hdr; + /* for now can only contain offVRAM. + * paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */ + VBOXCMDVBVA_ALLOCINFO Alloc; + uint32_t cSysMem; + VBOXCMDVBVA_SYSMEMEL aSysMem[1]; +} VBOXCMDVBVA_PAGING_TRANSFER; + +typedef struct VBOXCMDVBVA_PAGING_FILL +{ + VBOXCMDVBVA_HDR Hdr; + uint32_t cbFill; + uint32_t Pattern; + /* paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */ + VBOXCMDVBVAOFFSET offVRAM; +} VBOXCMDVBVA_PAGING_FILL; + +#define VBOXCMDVBVACTL_TYPE_ENABLE 1 +#define VBOXCMDVBVACTL_TYPE_3DCTL 2 + +typedef struct VBOXCMDVBVA_CTL +{ + uint32_t u32Type; + int32_t i32Result; +} VBOXCMDVBVA_CTL; + +typedef struct VBOXCMDVBVA_CTL_ENABLE +{ + VBOXCMDVBVA_CTL Hdr; + VBVAENABLE Enable; +} VBOXCMDVBVA_CTL_ENABLE; + +#define VBOXCMDVBVA3DCTL_TYPE_CONNECT 1 +#define VBOXCMDVBVA3DCTL_TYPE_DISCONNECT 2 +#define VBOXCMDVBVA3DCTL_TYPE_CMD 3 + +typedef struct VBOXCMDVBVA_3DCTL +{ + uint32_t u32Type; + uint32_t u32CmdClientId; +} VBOXCMDVBVA_3DCTL; + +typedef struct VBOXCMDVBVA_3DCTL_CONNECT +{ + VBOXCMDVBVA_3DCTL Hdr; + uint32_t u32MajorVersion; + uint32_t u32MinorVersion; + uint64_t u64Pid; +} VBOXCMDVBVA_3DCTL_CONNECT; + +typedef struct VBOXCMDVBVA_3DCTL_CMD +{ + VBOXCMDVBVA_3DCTL Hdr; + VBOXCMDVBVA_HDR Cmd; +} VBOXCMDVBVA_3DCTL_CMD; + +#pragma pack() + #ifdef VBOXVDMA_WITH_VBVA # pragma pack(1) diff --git a/include/VBox/VBoxVideo3D.h b/include/VBox/VBoxVideo3D.h index 91c6e306..56196dc0 100644 --- a/include/VBox/VBoxVideo3D.h +++ b/include/VBox/VBoxVideo3D.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -95,6 +95,8 @@ struct VBOXTLSREFDATA_DUMMY VBoxTlsRefAssertImpl(cRefs > 1 || (_p)->enmTlsRefState == VBOXTLSREFDATA_STATE_DESTROYING); \ } while (0) +#define VBoxTlsRefCountGet(_p) (ASMAtomicReadS32(&(_p)->cTlsRefs)) + #define VBoxTlsRefRelease(_p) do { \ int cRefs = ASMAtomicDecS32(&(_p)->cTlsRefs); \ VBoxTlsRefAssertImpl(cRefs >= 0); \ @@ -133,4 +135,10 @@ struct VBOXTLSREFDATA_DUMMY } \ } while (0) + +/* host 3D->Fe[/Qt] notification mechanism defines */ +#define VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA 2 +#define VBOX3D_NOTIFY_EVENT_TYPE_TEST_FUNCTIONAL 3 + + #endif /* #ifndef ___VBox_VBoxVideo3D_h */ diff --git a/include/VBox/VBoxVideoGuest.h b/include/VBox/VBoxVideoGuest.h index b0718231..e88afe6b 100644 --- a/include/VBox/VBoxVideoGuest.h +++ b/include/VBox/VBoxVideoGuest.h @@ -5,7 +5,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; @@ -38,6 +38,8 @@ RT_C_DECLS_BEGIN # include "ntddvdeo.h" # include RT_C_DECLS_END +#elif defined VBOX_GUESTR3XORGMOD +# include #else # include #endif @@ -123,6 +125,8 @@ DECLINLINE(void) VBoxVideoCmnPortWriteUchar(RTIOPORT Port, uint8_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUchar((PUCHAR)Port, Value); +#elif defined VBOX_GUESTR3XORGMOD + outb(Port, Value); #else /** @todo make these explicit */ ASMOutU8(Port, Value); #endif @@ -133,6 +137,8 @@ DECLINLINE(void) VBoxVideoCmnPortWriteUshort(RTIOPORT Port, uint16_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUshort((PUSHORT)Port,Value); +#elif defined VBOX_GUESTR3XORGMOD + outw(Port, Value); #else ASMOutU16(Port, Value); #endif @@ -143,6 +149,8 @@ DECLINLINE(void) VBoxVideoCmnPortWriteUlong(RTIOPORT Port, uint32_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUlong((PULONG)Port,Value); +#elif defined VBOX_GUESTR3XORGMOD + outl(Port, Value); #else ASMOutU32(Port, Value); #endif @@ -153,6 +161,8 @@ DECLINLINE(uint8_t) VBoxVideoCmnPortReadUchar(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUchar((PUCHAR)Port); +#elif defined VBOX_GUESTR3XORGMOD + return inb(Port); #else return ASMInU8(Port); #endif @@ -163,6 +173,8 @@ DECLINLINE(uint16_t) VBoxVideoCmnPortReadUshort(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUshort((PUSHORT)Port); +#elif defined VBOX_GUESTR3XORGMOD + return inw(Port); #else return ASMInU16(Port); #endif @@ -173,6 +185,8 @@ DECLINLINE(uint32_t) VBoxVideoCmnPortReadUlong(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUlong((PULONG)Port); +#elif defined VBOX_GUESTR3XORGMOD + return inl(Port); #else return ASMInU32(Port); #endif diff --git a/include/VBox/VBoxVideoHost3D.h b/include/VBox/VBoxVideoHost3D.h new file mode 100644 index 00000000..21c7da94 --- /dev/null +++ b/include/VBox/VBoxVideoHost3D.h @@ -0,0 +1,128 @@ +/** @file + * + * VirtualBox 3D host inter-components interfaces + */ + +/* + * Copyright (C) 2011-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 ___VBox_VBoxVideoHost3D_h +#define ___VBox_VBoxVideoHost3D_h +#include +#include + +/* screen update instance */ +typedef struct PDMIDISPLAYCONNECTOR *HVBOXCRCMDCLTSCR; +struct VBVACMDHDR; + +typedef struct VBOXCMDVBVA_HDR *PVBOXCMDVBVA_HDR; + +typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen); +typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_END)(HVBOXCRCMDCLTSCR hClt, unsigned uScreenId, int32_t x, int32_t y, uint32_t cx, uint32_t cy); +typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen, struct VBVACMDHDR *pCmd, size_t cbCmd); + +/*client callbacks to be used by the server + * when working in the CrCmd mode */ +typedef struct VBOXCRCMD_SVRENABLE_INFO +{ + HVBOXCRCMDCLTSCR hCltScr; + PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN pfnCltScrUpdateBegin; + PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS pfnCltScrUpdateProcess; + PFNVBOXCRCMD_CLTSCR_UPDATE_END pfnCltScrUpdateEnd; +} VBOXCRCMD_SVRENABLE_INFO; + +typedef void * HVBOXCRCMDSVR; + +/* enables the CrCmd interface, thus the hgcm interface gets disabled. + * all subsequent calls will be done in the thread Enable was done, + * until the Disable is called */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_ENABLE)(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo); +/* Opposite to Enable (see above) */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_DISABLE)(HVBOXCRCMDSVR hSvr); +/* process command */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_CMD)(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd); +/* process host control */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_HOSTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd); +/* process guest control */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_GUESTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd); +/* process SaveState */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_SAVESTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM); +/* process LoadState */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_LOADSTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version); + + +typedef struct VBOXCRCMD_SVRINFO +{ + HVBOXCRCMDSVR hSvr; + PFNVBOXCRCMD_SVR_ENABLE pfnEnable; + PFNVBOXCRCMD_SVR_DISABLE pfnDisable; + PFNVBOXCRCMD_SVR_CMD pfnCmd; + PFNVBOXCRCMD_SVR_HOSTCTL pfnHostCtl; + PFNVBOXCRCMD_SVR_GUESTCTL pfnGuestCtl; + PFNVBOXCRCMD_SVR_SAVESTATE pfnSaveState; + PFNVBOXCRCMD_SVR_LOADSTATE pfnLoadState; +} VBOXCRCMD_SVRINFO; + + +typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP +{ + VBOXVDMACMD_CHROMIUM_CTL Hdr; + union + { + void *pvVRamBase; + uint64_t uAlignment; + }; + uint64_t cbVRam; + /* out */ + struct VBOXCRCMD_SVRINFO CrCmdServerInfo; +} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP; + +typedef enum +{ + VBOXCRCMDCTL_TYPE_HGCM = 1, + VBOXCRCMDCTL_TYPE_DISABLE, + VBOXCRCMDCTL_TYPE_ENABLE, + VBOXCRCMDCTL_TYPE_32bit = 0x7fffffff +} VBOXCRCMDCTL_TYPE; + +typedef struct VBOXCRCMDCTL +{ + VBOXCRCMDCTL_TYPE enmType; + uint32_t u32Function; + /* not to be used by clients */ + union + { + void(*pfnInternal)(); + void* pvInternal; + }; +} VBOXCRCMDCTL; + +typedef struct VBOXVDMAHOST * HVBOXCRCMDCTL_REMAINING_HOST_COMMAND; + +typedef DECLCALLBACKPTR(uint8_t*, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND)(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hClient, uint32_t *pcbCtl, int prevCmdRc); + +typedef struct VBOXCRCMDCTL_ENABLE +{ + VBOXCRCMDCTL Hdr; + HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd; + PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd; +} VBOXCRCMDCTL_ENABLE; + +#endif /*#ifndef ___VBox_VBoxVideoHost3D_h*/ diff --git a/include/VBox/VDEPlugSymDefs.h b/include/VBox/VDEPlugSymDefs.h index 483b7834..fd11a8ca 100644 --- a/include/VBox/VDEPlugSymDefs.h +++ b/include/VBox/VDEPlugSymDefs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2008-2010 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/include/VBox/VMMDev.h b/include/VBox/VMMDev.h index fe81237d..fb850625 100644 --- a/include/VBox/VMMDev.h +++ b/include/VBox/VMMDev.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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,8 +35,10 @@ #include +#pragma pack(4) /* force structure dword packing here. */ RT_C_DECLS_BEGIN + /** @defgroup grp_vmmdev VMM Device * * Note! This interface cannot be changed, it can only be extended! @@ -114,6 +116,10 @@ RT_C_DECLS_BEGIN /** Maximum request packet size. */ #define VMMDEV_MAX_VMMDEVREQ_SIZE _1M +/** Maximum number of HGCM parameters. */ +#define VMMDEV_MAX_HGCM_PARMS 1024 +/** Maximum total size of hgcm buffers in one call. */ +#define VMMDEV_MAX_HGCM_DATA_SIZE UINT32_C(0x7FFFFFFF) /** * VMMDev request types. @@ -138,6 +144,7 @@ typedef enum VMMDevReq_ReportGuestInfo = 50, VMMDevReq_ReportGuestInfo2 = 58, /* since version 3.2.0 */ VMMDevReq_ReportGuestStatus = 59, /* since version 3.2.8 */ + VMMDevReq_ReportGuestUserState = 74, /* since version 4.3 */ /** * Retrieve a display resize request sent by the host using * @a IDisplay:setVideoModeHint. Deprecated. @@ -170,6 +177,7 @@ typedef enum VMMDevReq_ReportGuestCapabilities = 55, VMMDevReq_SetGuestCapabilities = 56, VMMDevReq_VideoModeSupported2 = 57, /* since version 3.2.0 */ + VMMDevReq_GetDisplayChangeRequestEx = 80, /* since version 4.2.4 */ #ifdef VBOX_WITH_HGCM VMMDevReq_HGCMConnect = 60, VMMDevReq_HGCMDisconnect = 61, @@ -231,7 +239,6 @@ typedef enum /** Version of VMMDevRequestHeader structure. */ #define VMMDEV_REQUEST_HEADER_VERSION (0x10001) -#pragma pack(4) /* force structure dword packing here. */ /** * Generic VMMDev request header. @@ -286,8 +293,7 @@ AssertCompileSize(VMMDevReqMouseStatus, 24+12); * cursor itself, the guest installs a hardware mouse driver. Don't ask the * guest to switch to a software cursor then. */ #define VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR RT_BIT(2) -/** The host does NOT provide support for drawing the cursor itself. - * This is for instance the case for the L4 console. */ +/** The host does NOT provide support for drawing the cursor itself. */ #define VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER RT_BIT(3) /** The guest can read VMMDev events to find out about pointer movement */ #define VMMDEV_MOUSE_NEW_PROTOCOL RT_BIT(4) @@ -799,6 +805,73 @@ typedef struct AssertCompileSize(VMMDevReportGuestStatus, 24+12); +/** + * The current status of specific guest user. + * This needs to be kept in sync with GuestUserState of the Main API! + */ +typedef enum VBoxGuestUserState +{ + VBoxGuestUserState_Unknown = 0, + VBoxGuestUserState_LoggedIn = 1, + VBoxGuestUserState_LoggedOut = 2, + VBoxGuestUserState_Locked = 3, + VBoxGuestUserState_Unlocked = 4, + VBoxGuestUserState_Disabled = 5, + VBoxGuestUserState_Idle = 6, + VBoxGuestUserState_InUse = 7, + VBoxGuestUserState_Created = 8, + VBoxGuestUserState_Deleted = 9, + VBoxGuestUserState_SessionChanged = 10, + VBoxGuestUserState_CredentialsChanged = 11, + VBoxGuestUserState_RoleChanged = 12, + VBoxGuestUserState_GroupAdded = 13, + VBoxGuestUserState_GroupRemoved = 14, + VBoxGuestUserState_Elevated = 15, + VBoxGuestUserState_SizeHack = 0x7fffffff +} VBoxGuestUserState; +AssertCompileSize(VBoxGuestUserState, 4); + + +/** + * Guest user status updates. + */ +typedef struct VBoxGuestUserStatus +{ + /** The guest user state to send. */ + VBoxGuestUserState state; + /** Size (in bytes) of szUser. */ + uint32_t cbUser; + /** Size (in bytes) of szDomain. */ + uint32_t cbDomain; + /** Size (in bytes) of aDetails. */ + uint32_t cbDetails; + /** Note: Here begins the dynamically + * allocated region. */ + /** Guest user to report state for. */ + char szUser[1]; + /** Domain the guest user is bound to. */ + char szDomain[1]; + /** Optional details of the state. */ + uint8_t aDetails[1]; +} VBoxGuestUserStatus; +AssertCompileSize(VBoxGuestUserStatus, 20); + + +/** + * Guest user status structure. + * + * Used by VMMDevReq_ReportGuestUserStatus. + */ +typedef struct +{ + /** Header. */ + VMMDevRequestHeader header; + /** Guest user status. */ + VBoxGuestUserStatus status; +} VMMDevReportGuestUserState; +AssertCompileSize(VMMDevReportGuestUserState, 24+20); + + /** * Guest statistics structure. * @@ -959,7 +1032,6 @@ AssertCompileSize(VMMDevGetStatisticsChangeRequest, 24+8); * * Used by VMMDevReq_QueryCredentials. */ -#pragma pack(4) typedef struct { /** Header. */ @@ -974,7 +1046,6 @@ typedef struct char szDomain[VMMDEV_CREDENTIALS_SZ_SIZE]; } VMMDevCredentials; AssertCompileSize(VMMDevCredentials, 24+4+3*128); -#pragma pack() /** @name Credentials request flag (VMMDevCredentials::u32Flags) * @{ */ @@ -1071,6 +1142,40 @@ typedef struct AssertCompileSize(VMMDevDisplayChangeRequest2, 24+20); +/** + * Display change request structure, version Extended. + * + * Used by VMMDevReq_GetDisplayChangeRequestEx. + */ +typedef struct +{ + /** Header. */ + VMMDevRequestHeader header; + /** Horizontal pixel resolution (0 = do not change). */ + uint32_t xres; + /** Vertical pixel resolution (0 = do not change). */ + uint32_t yres; + /** Bits per pixel (0 = do not change). */ + uint32_t bpp; + /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates + * that the request is a response to that event. + * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */ + uint32_t eventAck; + /** 0 for primary display, 1 for the first secondary, etc. */ + uint32_t display; + /** New OriginX of secondary virtual screen */ + uint32_t cxOrigin; + /** New OriginY of secondary virtual screen */ + uint32_t cyOrigin; + /** Change in origin of the secondary virtaul scree is + * required */ + bool fChangeOrigin; + /** secondary virtual screen enabled or disabled */ + bool fEnabled; +} VMMDevDisplayChangeRequestEx; +AssertCompileSize(VMMDevDisplayChangeRequestEx, 24+32); + + /** * Video mode supported request structure. * @@ -1388,8 +1493,6 @@ typedef struct AssertCompileSize(VMMDevReqWriteCoreDump, 24+4); -#pragma pack() - #ifdef VBOX_WITH_HGCM @@ -1401,8 +1504,6 @@ AssertCompileSize(VMMDevReqWriteCoreDump, 24+4); # define VBOX_HGCM_REQ_CANCELLED (0x2) /** @} */ -# pragma pack(4) - /** * HGCM request header. */ @@ -1745,7 +1846,6 @@ typedef struct } HGCMPageListInfo; AssertCompileSize(HGCMPageListInfo, 4+2+2+8); -# pragma pack() /** Get the pointer to the first parmater of a HGCM call request. */ # define VMMDEV_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall))) @@ -1800,6 +1900,7 @@ AssertCompileSize(VMMDevHGCMCancel2, 24+4); /** * Inline helper to determine the request size for the given operation. + * Returns 0 if the given operation is not handled and/or supported. * * @returns Size. * @param requestType The VMMDev request type. @@ -1835,10 +1936,14 @@ DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType) return sizeof(VMMDevReportGuestInfo2); case VMMDevReq_ReportGuestStatus: return sizeof(VMMDevReportGuestStatus); + case VMMDevReq_ReportGuestUserState: + return sizeof(VMMDevReportGuestUserState); case VMMDevReq_GetDisplayChangeRequest: return sizeof(VMMDevDisplayChangeRequest); case VMMDevReq_GetDisplayChangeRequest2: return sizeof(VMMDevDisplayChangeRequest2); + case VMMDevReq_GetDisplayChangeRequestEx: + return sizeof(VMMDevDisplayChangeRequestEx); case VMMDevReq_VideoModeSupported: return sizeof(VMMDevVideoModeSupportedRequest); case VMMDevReq_GetHeightReduction: @@ -1907,8 +2012,10 @@ DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType) case VMMDevReq_GetSessionId: return sizeof(VMMDevReqSessionId); default: - return 0; + break; } + + return 0; } @@ -1944,7 +2051,6 @@ DECLINLINE(int) vmmdevInitRequest(VMMDevRequestHeader *req, VMMDevRequestType ty * * @todo Where does this fit in? */ -#pragma pack(1) /* unnecessary */ typedef struct VBVACMDHDR { /** Coordinates of affected rectangle. */ @@ -1953,7 +2059,7 @@ typedef struct VBVACMDHDR uint16_t w; uint16_t h; } VBVACMDHDR; -#pragma pack() +AssertCompileSize(VBVACMDHDR, 8); /** @name VBVA ring defines. * @@ -1983,6 +2089,8 @@ typedef struct VBVACMDHDR #define VBVA_F_MODE_VRDP_RESET (0x00000004) #define VBVA_F_MODE_VRDP_ORDER_MASK (0x00000008) +#define VBVA_F_STATE_PROCESSING (0x00010000) + #define VBVA_F_RECORD_PARTIAL (0x80000000) /** @} */ @@ -2002,7 +2110,6 @@ AssertCompileSize(VBVARECORD, 4); * * This is a subsection of the VMMDevMemory structure. */ -#pragma pack(1) /* paranoia */ typedef struct VBVAMEMORY { /** VBVA_F_MODE_*. */ @@ -2029,14 +2136,12 @@ typedef struct VBVAMEMORY uint32_t fu32SupportedOrders; } VBVAMEMORY; -#pragma pack() AssertCompileSize(VBVAMEMORY, 12 + (_4M-_1K) + 4*64 + 12); /** * The layout of VMMDEV RAM region that contains information for guest. */ -#pragma pack(1) /* paranoia */ typedef struct VMMDevMemory { /** The size of this structure. */ @@ -2065,13 +2170,15 @@ typedef struct VMMDevMemory } VMMDevMemory; AssertCompileSize(VMMDevMemory, 8+8 + (12 + (_4M-_1K) + 4*64 + 12) ); -#pragma pack() +AssertCompileMemberOffset(VMMDevMemory, vbvaMemory, 16); /** Version of VMMDevMemory structure (VMMDevMemory::u32Version). */ #define VMMDEV_MEMORY_VERSION (1) /** @} */ + RT_C_DECLS_END +#pragma pack() #endif diff --git a/include/VBox/VMMDev2.h b/include/VBox/VMMDev2.h index 3a8ebbed..c8709f72 100644 --- a/include/VBox/VMMDev2.h +++ b/include/VBox/VMMDev2.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2009 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/include/VBox/apic.h b/include/VBox/apic.h index 2d0b8a6f..0b22f11e 100644 --- a/include/VBox/apic.h +++ b/include/VBox/apic.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2010-2011 Oracle Corporation + * Copyright (C) 2010-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; @@ -31,28 +31,41 @@ #include #define APIC_REG_VERSION 0x0030 -#define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) -#define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) +#define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) +#define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) -/* defines according to Figure 10-8 of the Intel Software Developers Manual Vol 3A */ +/* Defines according to Figure 10-8 of the Intel Software Developers Manual Vol 3A */ #define APIC_REG_LVT_LINT0 0x0350 #define APIC_REG_LVT_LINT1 0x0360 #define APIC_REG_LVT_ERR 0x0370 #define APIC_REG_LVT_PC 0x0340 #define APIC_REG_LVT_THMR 0x0330 -#define APIC_REG_LVT_MODE_MASK (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -#define APIC_REG_LVT_MODE_FIXED 0 -#define APIC_REG_LVT_MODE_NMI (RT_BIT(10)) -#define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -#define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) -#define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) -#define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) -#define APIC_REG_LVT_MASKED RT_BIT(16) +#define APIC_REG_LVT_MODE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +#define APIC_REG_LVT_MODE_FIXED 0 +#define APIC_REG_LVT_MODE_NMI RT_BIT(10) +#define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +#define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) +#define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) +#define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) +#define APIC_REG_LVT_MASKED RT_BIT(16) DECLINLINE(uint32_t) ApicRegRead(void *pvBase, uint32_t offReg) { return *(const volatile uint32_t *)((uintptr_t)pvBase + offReg); } + +#ifdef ___iprt_asm_amd64_x86_h +/** + * Reads an X2APIC register. + * + * @param offReg MMIO offset, APIC_REG_XXX. + */ +DECLINLINE(uint32_t) ApicX2RegRead32(uint32_t offReg) +{ + return ASMRdMsr((offReg >> 4) + MSR_IA32_X2APIC_START); +} #endif +#endif /* ___VBox_apic_h */ + diff --git a/include/VBox/apic.mac b/include/VBox/apic.mac index 57eb7ca8..9f6bea48 100644 --- a/include/VBox/apic.mac +++ b/include/VBox/apic.mac @@ -1,19 +1,21 @@ %ifndef ___VBox_apic_h %define ___VBox_apic_h %define APIC_REG_VERSION 0x0030 -%define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) -%define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) +%define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) +%define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) %define APIC_REG_LVT_LINT0 0x0350 %define APIC_REG_LVT_LINT1 0x0360 %define APIC_REG_LVT_ERR 0x0370 %define APIC_REG_LVT_PC 0x0340 %define APIC_REG_LVT_THMR 0x0330 -%define APIC_REG_LVT_MODE_MASK (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -%define APIC_REG_LVT_MODE_FIXED 0 -%define APIC_REG_LVT_MODE_NMI (RT_BIT(10)) -%define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -%define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) -%define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) -%define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) -%define APIC_REG_LVT_MASKED RT_BIT(16) +%define APIC_REG_LVT_MODE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +%define APIC_REG_LVT_MODE_FIXED 0 +%define APIC_REG_LVT_MODE_NMI RT_BIT(10) +%define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +%define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) +%define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) +%define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) +%define APIC_REG_LVT_MASKED RT_BIT(16) +%ifdef ___iprt_asm_amd64_x86_h +%endif %endif diff --git a/include/VBox/asmdefs.mac b/include/VBox/asmdefs.mac index 96b0e52d..b877e632 100644 --- a/include/VBox/asmdefs.mac +++ b/include/VBox/asmdefs.mac @@ -3,7 +3,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/include/VBox/bioslogo.h b/include/VBox/bioslogo.h index b78d1cae..1c5fd041 100644 --- a/include/VBox/bioslogo.h +++ b/include/VBox/bioslogo.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/include/VBox/cdefs.h b/include/VBox/cdefs.h index 652f7f6b..0744b763 100644 --- a/include/VBox/cdefs.h +++ b/include/VBox/cdefs.h @@ -3,7 +3,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; @@ -203,9 +203,17 @@ * @param type The return type of the function declaration. */ #ifdef IN_SUP_R3 -# define SUPR3DECL(type) DECLEXPORT(type) VBOXCALL +# ifdef IN_SUP_STATIC +# define SUPR3DECL(type) DECLHIDDEN(type) VBOXCALL +# else +# define SUPR3DECL(type) DECLEXPORT(type) VBOXCALL +# endif #else -# define SUPR3DECL(type) DECLIMPORT(type) VBOXCALL +# ifdef IN_SUP_STATIC +# define SUPR3DECL(type) DECLHIDDEN(type) VBOXCALL +# else +# define SUPR3DECL(type) DECLIMPORT(type) VBOXCALL +# endif #endif /** @def IN_SUP_R0 @@ -409,7 +417,7 @@ * VMM internal function, ring-0 + raw-mode context. * @param type The return type of the function declaration. */ -#ifdef IN_VMM_RZ +#if defined(IN_VMM_RC) || defined(IN_VMM_R0) # define VMMRZ_INT_DECL(type) DECLHIDDEN(type) VBOXCALL #else # define VMMRZ_INT_DECL(type) DECL_INVALID(type) diff --git a/include/VBox/com/AutoLock.h b/include/VBox/com/AutoLock.h index 9c700dd9..12eeccae 100644 --- a/include/VBox/com/AutoLock.h +++ b/include/VBox/com/AutoLock.h @@ -1,5 +1,4 @@ /** @file - * * Automatic locks, implementation */ @@ -24,8 +23,8 @@ * terms and conditions of either the GPL or the CDDL or both. */ -#ifndef ____H_AUTOLOCK -#define ____H_AUTOLOCK +#ifndef ___VBox_com_AutoLock_h +#define ___VBox_com_AutoLock_h #include @@ -633,6 +632,6 @@ public: } /* namespace util */ -#endif // ____H_AUTOLOCK +#endif /* vi: set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/include/VBox/com/ErrorInfo.h b/include/VBox/com/ErrorInfo.h index 1037b253..869b9983 100644 --- a/include/VBox/com/ErrorInfo.h +++ b/include/VBox/com/ErrorInfo.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * ErrorInfo class declaration + * MS COM / XPCOM Abstraction Layer - ErrorInfo class declaration. */ /* - * 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; @@ -174,6 +173,7 @@ public: : mIsBasicAvailable(false), mIsFullAvailable(false), mResultCode(S_OK), + mResultDetail(0), m_pNext(NULL) { init(); @@ -183,6 +183,7 @@ public: : mIsBasicAvailable(false), mIsFullAvailable(false), mResultCode(S_OK), + mResultDetail(0), m_pNext(NULL) { init(pObj, aIID); @@ -191,7 +192,7 @@ public: /** Specialization for the IVirtualBoxErrorInfo smart pointer */ ErrorInfo (const ComPtr &aPtr) : mIsBasicAvailable (false), mIsFullAvailable (false) - , mResultCode (S_OK) + , mResultCode (S_OK), mResultDetail(0) { init (aPtr); } /** @@ -204,7 +205,7 @@ public: */ ErrorInfo (IVirtualBoxErrorInfo *aInfo) : mIsBasicAvailable (false), mIsFullAvailable (false) - , mResultCode (S_OK) + , mResultCode (S_OK), mResultDetail(0) { init (aInfo); } ErrorInfo(const ErrorInfo &x) @@ -266,6 +267,14 @@ public: return mResultCode; } + /** + * Returns the (optional) result detail code of the failed operation. + */ + LONG getResultDetail() const + { + return mResultDetail; + } + /** * Returns the IID of the interface that defined the error. */ @@ -330,6 +339,8 @@ public: return mCalleeName; } + HRESULT getVirtualBoxErrorInfo(ComPtr &pVirtualBoxErrorInfo); + /** * Resets all collected error information. #isBasicAvailable() and * #isFullAvailable will return @c true after this method is called. @@ -359,6 +370,7 @@ protected: bool mIsFullAvailable : 1; HRESULT mResultCode; + LONG mResultDetail; Guid mInterfaceID; Bstr mComponent; Bstr mText; @@ -443,6 +455,19 @@ public: init(true /* aKeepObj */); } + /** + * Constructs a new instance from an ErrorInfo object, to inject a full + * error info created elsewhere. + * + * @param aInfo @c true to prevent fetching error info and leave + * the instance uninitialized. + */ + ErrorInfoKeeper(const ErrorInfo &aInfo) + : ErrorInfo(false), mForgot(false) + { + copyFrom(aInfo); + } + /** * Destroys this instance and automatically calls #restore() which will * either restore error info fetched by the constructor or do nothing diff --git a/include/VBox/com/EventQueue.h b/include/VBox/com/EventQueue.h index 14f4fc84..2f6587ce 100644 --- a/include/VBox/com/EventQueue.h +++ b/include/VBox/com/EventQueue.h @@ -1,10 +1,10 @@ +/* $Id: EventQueue.h $ */ /** @file - * MS COM / XPCOM Abstraction Layer: - * Event and EventQueue class declaration + * Event queue class declaration. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * 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; @@ -27,11 +27,10 @@ #ifndef ___VBox_com_EventQueue_h #define ___VBox_com_EventQueue_h -#ifndef VBOX_WITH_XPCOM -# include -#else // VBOX_WITH_XPCOM -# include -#endif // VBOX_WITH_XPCOM +#include + +#include +#include #include #include @@ -52,8 +51,21 @@ class Event { public: - Event() {} - virtual ~Event() {}; + Event(void) : + mRefCount(0) { } + virtual ~Event(void) { AssertMsg(!mRefCount, + ("Reference count of event=%p not 0 on destruction (is %RU32)\n", + this, mRefCount)); } +public: + + uint32_t AddRef(void) { return ASMAtomicIncU32(&mRefCount); } + void Release(void) + { + Assert(mRefCount); + uint32_t cRefs = ASMAtomicDecU32(&mRefCount); + if (!cRefs) + delete this; + } protected: @@ -63,78 +75,56 @@ protected: * * @return reserved, should be NULL. */ - virtual void *handler() { return NULL; } + virtual void *handler(void) { return NULL; } friend class EventQueue; + +protected: + + /** The event's reference count. */ + uint32_t mRefCount; }; +typedef std::list< Event* > EventQueueList; +typedef std::list< Event* >::iterator EventQueueListIterator; +typedef std::list< Event* >::const_iterator EventQueueListIteratorConst; + /** * Simple event queue. - * - * When using XPCOM, this will map onto the default XPCOM queue for the thread. - * So, if a queue is created on the main thread, it automatically processes - * XPCOM/IPC events while waiting. - * - * When using Windows, Darwin and OS/2, this will map onto the native thread - * queue/runloop. So, windows messages and what not will be processed while - * waiting for events. - * - * @note It is intentional that there is no way to retrieve arbitrary - * events and controlling their processing. There is no use case which - * warrants introducing the complexity of platform independent events. */ class EventQueue { public: - EventQueue(); - ~EventQueue(); + EventQueue(void); + virtual ~EventQueue(void); + +public: BOOL postEvent(Event *event); int processEventQueue(RTMSINTERVAL cMsTimeout); + int processPendingEvents(size_t cNumEvents); int interruptEventQueueProcessing(); - int getSelectFD(); - static int init(); - static int uninit(); - static EventQueue *getMainEventQueue(); - -#ifdef VBOX_WITH_XPCOM - already_AddRefed getIEventQueue() - { - return mEventQ.get(); - } -#else - static int dispatchMessageOnWindows(MSG const *pMsg, int rc); -#endif private: - static EventQueue *sMainQueue; - -#ifndef VBOX_WITH_XPCOM - - /** The thread which the queue belongs to. */ - DWORD mThreadId; - /** Duplicated thread handle for MsgWaitForMultipleObjects. */ - HANDLE mhThread; -#else // VBOX_WITH_XPCOM - - /** Whether it was created (and thus needs destroying) or if a queue already - * associated with the thread was used. */ - bool mEQCreated; - - /** Whether event processing should be interrupted. */ - bool mInterrupted; - - nsCOMPtr mEventQ; - nsCOMPtr mEventQService; - - static void *PR_CALLBACK plEventHandler(PLEvent *self); - static void PR_CALLBACK plEventDestructor(PLEvent *self); - -#endif // VBOX_WITH_XPCOM + /** Critical section for serializing access to this + * event queue. */ + RTCRITSECT mCritSect; + /** Number of concurrent users. At the moment we + * only support one concurrent user at a time when + calling processEventQueue(). */ + uint32_t mUserCnt; + /** Event semaphore for getting notified on new + * events being handled. */ + RTSEMEVENT mSemEvent; + /** The actual event queue, implemented as a list. */ + EventQueueList mEvents; + /** Shutdown indicator. */ + bool mShutdown; }; } /* namespace com */ #endif + diff --git a/include/VBox/com/Guid.h b/include/VBox/com/Guid.h index c55d69dc..969780b5 100644 --- a/include/VBox/com/Guid.h +++ b/include/VBox/com/Guid.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; @@ -47,6 +47,13 @@ namespace com { +typedef enum + { + ZERO_GUID, + NORMAL_GUID, + INVALID_GUID + }GuidState_t; + /** * Helper class that represents the UUID type and hides platform-specific * implementation details. @@ -59,18 +66,27 @@ public: { ::RTUuidClear(&mUuid); refresh(); + mGuidState = ZERO_GUID; } Guid(const Guid &that) { mUuid = that.mUuid; refresh(); + if (isEmpty()) + mGuidState = ZERO_GUID; + else + mGuidState = NORMAL_GUID; } Guid(const RTUUID &that) { mUuid = that; refresh(); + if (isEmpty()) + mGuidState = ZERO_GUID; + else + mGuidState = NORMAL_GUID; } Guid(const GUID &that) @@ -78,6 +94,10 @@ public: AssertCompileSize(GUID, sizeof(RTUUID)); ::memcpy(&mUuid, &that, sizeof(GUID)); refresh(); + if (isEmpty()) + mGuidState = ZERO_GUID; + else + mGuidState = NORMAL_GUID; } /** @@ -91,9 +111,17 @@ public: */ Guid(const char *that) { + mGuidState = NORMAL_GUID; + int rc = ::RTUuidFromStr(&mUuid, that); + if (RT_FAILURE(rc)) + { ::RTUuidClear(&mUuid); + mGuidState = INVALID_GUID; + } + else if(isEmpty()) + mGuidState = ZERO_GUID; refresh(); } @@ -108,49 +136,84 @@ public: */ Guid(const Bstr &that) { - int rc = !that.isEmpty() - ? ::RTUuidFromUtf16(&mUuid, that.raw()) - : VERR_INVALID_UUID_FORMAT; - if (RT_FAILURE(rc)) + mGuidState = NORMAL_GUID; + + if (that.isEmpty()) + { ::RTUuidClear(&mUuid); + mGuidState = ZERO_GUID; + } + else + { + int rc = ::RTUuidFromUtf16(&mUuid, that.raw()); + if (RT_FAILURE(rc)) + { + ::RTUuidClear(&mUuid); + mGuidState = INVALID_GUID; + } + } + refresh(); } Guid& operator=(const Guid &that) { + mGuidState = NORMAL_GUID; ::memcpy(&mUuid, &that.mUuid, sizeof (RTUUID)); + if (isEmpty()) + mGuidState = ZERO_GUID; refresh(); return *this; } Guid& operator=(const GUID &guid) { + mGuidState = NORMAL_GUID; ::memcpy(&mUuid, &guid, sizeof (GUID)); + if (isEmpty()) + mGuidState = ZERO_GUID; refresh(); return *this; } Guid& operator=(const RTUUID &guid) { + mGuidState = NORMAL_GUID; ::memcpy(&mUuid, &guid, sizeof (RTUUID)); + if (isEmpty()) + mGuidState = ZERO_GUID; refresh(); return *this; } Guid& operator=(const char *str) { + mGuidState = NORMAL_GUID; int rc = ::RTUuidFromStr(&mUuid, str); + if (RT_FAILURE(rc)) + { ::RTUuidClear(&mUuid); + mGuidState = INVALID_GUID; + } + else + { + if (isEmpty()) + mGuidState = ZERO_GUID; + } + refresh(); + return *this; } void create() { ::RTUuidCreate(&mUuid); + mGuidState = NORMAL_GUID; refresh(); } void clear() { ::RTUuidClear(&mUuid); + mGuidState = ZERO_GUID; refresh(); } @@ -163,7 +226,18 @@ public: Utf8Str toString() const { char buf[RTUUID_STR_LENGTH]; + + ::memset(buf,0,RTUUID_STR_LENGTH); + + if (mGuidState == INVALID_GUID) + { + /* What to return in case of wrong Guid */ + return Utf8Str("00000000-0000-0000-0000-00000000000"); + } + ::RTUuidToStr(&mUuid, buf, RTUUID_STR_LENGTH); + + return Utf8Str(buf); } @@ -175,10 +249,19 @@ public: */ Utf8Str toStringCurly() const { + + if (mGuidState == INVALID_GUID) + { + /* What to return in case of wrong Guid */ + return Utf8Str("{00000000-0000-0000-0000-00000000000}"); + } + char buf[RTUUID_STR_LENGTH + 2] = "{"; + ::RTUuidToStr(&mUuid, buf + 1, RTUUID_STR_LENGTH); buf[sizeof(buf) - 2] = '}'; buf[sizeof(buf) - 1] = '\0'; + return Utf8Str(buf); } @@ -190,22 +273,26 @@ public: */ Bstr toUtf16() const { - if (isEmpty()) - return Bstr(); + if (mGuidState == INVALID_GUID) + return Bstr("00000000-0000-0000-0000-00000000000"); RTUTF16 buf[RTUUID_STR_LENGTH]; ::RTUuidToUtf16(&mUuid, buf, RTUUID_STR_LENGTH); return Bstr(buf); } - bool isEmpty() const + bool isValid() const { - return ::RTUuidIsNull(&mUuid); + bool res = true; + if (mGuidState == INVALID_GUID) + res = false; + + return res; } - bool isNotEmpty() const + bool isZero() const { - return !::RTUuidIsNull(&mUuid); + return (::RTUuidIsNull(&mUuid) && mGuidState == ZERO_GUID); } bool operator==(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) == 0; } @@ -256,6 +343,7 @@ public: { if (ppGuid) *ppGuid = (nsID *)nsMemory::Clone(&mUuid, sizeof(nsID)); + return *this; } @@ -308,6 +396,18 @@ public: */ static const Guid Empty; +protected: + + bool isEmpty() const + { + return ::RTUuidIsNull(&mUuid); + } + + bool isNotEmpty() const + { + return !::RTUuidIsNull(&mUuid); + } + private: /** * Refresh the debug-only UUID string. @@ -319,14 +419,16 @@ private: inline void refresh() { #ifdef DEBUG - ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH); - m_pcszUUID = mszUuid; +// ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH); +// m_pcszUUID = mszUuid; #endif } /** The UUID. */ RTUUID mUuid; + GuidState_t mGuidState; + #ifdef DEBUG /** String representation of mUuid for printing in the debugger. */ char mszUuid[RTUUID_STR_LENGTH]; @@ -334,18 +436,19 @@ private: const char *m_pcszUUID; #endif }; - +/* inline Bstr asGuidStr(const Bstr& str) { Guid guid(str); return guid.isEmpty() ? Bstr() : guid.toUtf16(); } - -inline bool isValidGuid(const Bstr& str) -{ - Guid guid(str); - return !guid.isEmpty(); -} +*/ +//inline bool isValidGuid(const Bstr& str) +//{ +// Guid guid(str); +// return guid.isValid(); +//// return !guid.isEmpty(); +//} } /* namespace com */ diff --git a/include/VBox/com/MultiResult.h b/include/VBox/com/MultiResult.h index 705e1dbe..e8946468 100644 --- a/include/VBox/com/MultiResult.h +++ b/include/VBox/com/MultiResult.h @@ -1,8 +1,6 @@ /* $Id: MultiResult.h $ */ - /** @file - * MS COM / XPCOM Abstraction Layer: - * MultiResult class declarations + * MS COM / XPCOM Abstraction Layer - MultiResult class declarations. */ /* @@ -258,5 +256,5 @@ private: } /* namespace com */ -#endif /* ___VBox_com_MultiResult_h */ +#endif /* !___VBox_com_MultiResult_h */ diff --git a/include/VBox/com/NativeEventQueue.h b/include/VBox/com/NativeEventQueue.h new file mode 100644 index 00000000..96a872f1 --- /dev/null +++ b/include/VBox/com/NativeEventQueue.h @@ -0,0 +1,140 @@ +/** @file + * MS COM / XPCOM Abstraction Layer: + * Event and EventQueue class declaration + */ + +/* + * 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; + * 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 ___VBox_com_EventQueue_h +#define ___VBox_com_EventQueue_h + +#ifndef VBOX_WITH_XPCOM +# include +#else // VBOX_WITH_XPCOM +# include +#endif // VBOX_WITH_XPCOM + +#include +#include + +namespace com +{ + +class MainEventQueue; + +/** + * Base class for all events. Intended to be subclassed to introduce new + * events and handlers for them. + * + * Subclasses usually reimplement virtual #handler() (that does nothing by + * default) and add new data members describing the event. + */ +class NativeEvent +{ +public: + + NativeEvent() {} + virtual ~NativeEvent() {}; + +protected: + + /** + * Event handler. Called in the context of the event queue's thread. + * Always reimplemented by subclasses + * + * @return reserved, should be NULL. + */ + virtual void *handler() { return NULL; } + + friend class NativeEventQueue; +}; + +/** + * Simple event queue. + * + * When using XPCOM, this will map onto the default XPCOM queue for the thread. + * So, if a queue is created on the main thread, it automatically processes + * XPCOM/IPC events while waiting. + * + * When using Windows, Darwin and OS/2, this will map onto the native thread + * queue/runloop. So, windows messages and what not will be processed while + * waiting for events. + * + * @note It is intentional that there is no way to retrieve arbitrary + * events and controlling their processing. There is no use case which + * warrants introducing the complexity of platform independent events. + */ +class NativeEventQueue +{ +public: + + NativeEventQueue(); + virtual ~NativeEventQueue(); + + BOOL postEvent(NativeEvent *event); + int processEventQueue(RTMSINTERVAL cMsTimeout); + int interruptEventQueueProcessing(); + int getSelectFD(); + static int init(); + static int uninit(); + static NativeEventQueue *getMainEventQueue(); + +#ifdef VBOX_WITH_XPCOM + already_AddRefed getIEventQueue() + { + return mEventQ.get(); + } +#else + static int dispatchMessageOnWindows(MSG const *pMsg, int rc); +#endif + +private: + static NativeEventQueue *sMainQueue; + +#ifndef VBOX_WITH_XPCOM + + /** The thread which the queue belongs to. */ + DWORD mThreadId; + /** Duplicated thread handle for MsgWaitForMultipleObjects. */ + HANDLE mhThread; + +#else // VBOX_WITH_XPCOM + + /** Whether it was created (and thus needs destroying) or if a queue already + * associated with the thread was used. */ + bool mEQCreated; + + /** Whether event processing should be interrupted. */ + bool mInterrupted; + + nsCOMPtr mEventQ; + nsCOMPtr mEventQService; + + static void *PR_CALLBACK plEventHandler(PLEvent *self); + static void PR_CALLBACK plEventDestructor(PLEvent *self); + +#endif // VBOX_WITH_XPCOM +}; + +} /* namespace com */ + +#endif diff --git a/include/VBox/com/VirtualBox.h b/include/VBox/com/VirtualBox.h index 92fe1e84..288ed8ff 100644 --- a/include/VBox/com/VirtualBox.h +++ b/include/VBox/com/VirtualBox.h @@ -1,22 +1,19 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * VirtualBox COM Library definitions. + * MS COM / XPCOM Abstraction Layer - VirtualBox COM Library definitions. * - * Note: This is the main header file that COM/XPCOM clients - * include; however, it is only a wrapper around another - * platform-dependent include file that contains the real - * COM/XPCOM interface declarations. That other include file - * is generated automatically at build time from - * /src/VBox/Main/idl/VirtualBox.xidl, which contains all - * the VirtualBox interfaces; the include file is called - * VirtualBox.h on Windows hosts and VirtualBox_XPCOM.h - * on Linux hosts. The build process places it in - * out//bin/sdk/include, from where it gets - * included by the rest of the VirtualBox code. + * @note This is the main header file that COM/XPCOM clients include; however, + * it is only a wrapper around another platform-dependent include file + * that contains the real COM/XPCOM interface declarations. That other + * include file is generated automatically at build time from + * /src/VBox/Main/idl/VirtualBox.xidl, which contains all the VirtualBox + * interfaces; the include file is called VirtualBox.h on Windows hosts + * and VirtualBox_XPCOM.h on Linux hosts. The build process places it in + * out//bin/sdk/include, from where it gets + * included by the rest of the VirtualBox code. */ /* - * 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; @@ -53,3 +50,4 @@ #include "VBox/com/ptr.h" #endif + diff --git a/include/VBox/com/array.h b/include/VBox/com/array.h index 7f1796d9..77f9d60b 100644 --- a/include/VBox/com/array.h +++ b/include/VBox/com/array.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Safe array helper class declaration + * MS COM / XPCOM Abstraction Layer - Safe array helper class declaration. */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -608,21 +607,18 @@ public: */ SafeArray(ComSafeArrayIn(T, aArg)) { + if (aArg) + { #ifdef VBOX_WITH_XPCOM - AssertReturnVoid(aArg != NULL); - - m.size = aArgSize; - m.arr = aArg; - m.isWeak = true; + m.size = aArgSize; + m.arr = aArg; + m.isWeak = true; #else /* !VBOX_WITH_XPCOM */ - AssertReturnVoid(aArg != NULL); - SAFEARRAY *arg = aArg; + SAFEARRAY *arg = aArg; - if (arg) - { AssertReturnVoid(arg->cDims == 1); VARTYPE vt; @@ -634,12 +630,12 @@ public: rc = SafeArrayAccessData(arg, (void HUGEP **)&m.raw); AssertComRCReturnVoid(rc); - } - m.arr = arg; - m.isWeak = true; + m.arr = arg; + m.isWeak = true; #endif /* !VBOX_WITH_XPCOM */ + } } /** @@ -975,7 +971,7 @@ public: */ virtual SafeArray &detachTo(ComSafeArrayOut(T, aArg)) { - AssertReturn(m.isWeak == false, *this); + AssertReturn(!m.isWeak, *this); #ifdef VBOX_WITH_XPCOM @@ -1242,6 +1238,34 @@ inline void com::SafeArray::initFrom(const BYTE* aPtr, size_t aSize) } +template<> +inline void com::SafeArray::initFrom(const com::SafeArray & aRef) +{ + size_t sSize = aRef.size(); + resize(sSize); + ::memcpy(raw(), aRef.raw(), sSize * sizeof(SHORT)); +} +template<> +inline void com::SafeArray::initFrom(const SHORT* aPtr, size_t aSize) +{ + resize(aSize); + ::memcpy(raw(), aPtr, aSize * sizeof(SHORT)); +} + +template<> +inline void com::SafeArray::initFrom(const com::SafeArray & aRef) +{ + size_t sSize = aRef.size(); + resize(sSize); + ::memcpy(raw(), aRef.raw(), sSize * sizeof(USHORT)); +} +template<> +inline void com::SafeArray::initFrom(const USHORT* aPtr, size_t aSize) +{ + resize(aSize); + ::memcpy(raw(), aPtr, aSize * sizeof(USHORT)); +} + template<> inline void com::SafeArray::initFrom(const com::SafeArray & aRef) { @@ -1523,21 +1547,18 @@ public: */ SafeIfaceArray(ComSafeArrayIn(I *, aArg)) { + if (aArg) + { #ifdef VBOX_WITH_XPCOM - AssertReturnVoid(aArg != NULL); - - Base::m.size = aArgSize; - Base::m.arr = aArg; - Base::m.isWeak = true; + Base::m.size = aArgSize; + Base::m.arr = aArg; + Base::m.isWeak = true; #else /* !VBOX_WITH_XPCOM */ - AssertReturnVoid(aArg != NULL); - SAFEARRAY *arg = aArg; + SAFEARRAY *arg = aArg; - if (arg) - { AssertReturnVoid(arg->cDims == 1); VARTYPE vt; @@ -1555,12 +1576,12 @@ public: rc = SafeArrayAccessData(arg, (void HUGEP **)&m.raw); AssertComRCReturnVoid(rc); - } - m.arr = arg; - m.isWeak = true; + m.arr = arg; + m.isWeak = true; #endif /* !VBOX_WITH_XPCOM */ + } } /** @@ -1699,4 +1720,5 @@ public: /** @} */ -#endif /* ___VBox_com_array_h */ +#endif /* !___VBox_com_array_h */ + diff --git a/include/VBox/com/assert.h b/include/VBox/com/assert.h index 0a9b1afd..900ce131 100644 --- a/include/VBox/com/assert.h +++ b/include/VBox/com/assert.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Assertion macros for COM/XPCOM + * MS COM / XPCOM Abstraction Layer - Assertion macros for COM/XPCOM. */ /* - * 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; @@ -106,3 +105,4 @@ if (!SUCCEEDED (rc)) { AssertComRC (rc); throw rc; } else do {} while (0) #endif // !___VBox_com_assert_h + diff --git a/include/VBox/com/com.h b/include/VBox/com/com.h index 524c89c6..92502689 100644 --- a/include/VBox/com/com.h +++ b/include/VBox/com/com.h @@ -1,6 +1,5 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * COM initialization / shutdown + * MS COM / XPCOM Abstraction Layer - COM initialization / shutdown. */ /* diff --git a/include/VBox/com/defs.h b/include/VBox/com/defs.h index aa9800dd..65db7938 100644 --- a/include/VBox/com/defs.h +++ b/include/VBox/com/defs.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Common definitions + * MS COM / XPCOM Abstraction Layer - Common definitions. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -59,16 +58,16 @@ # define RT_MAX(Value1, Value2) ( (Value1) >= (Value2) ? (Value1) : (Value2) ) # endif -#endif /* defined (RT_OS_OS2) */ +#endif /* defined(RT_OS_OS2) */ /* Include iprt/types.h (which also includes iprt/types.h) now to make sure iprt * gets to stdint.h first, otherwise a system/xpcom header might beat us and * we'll be without the macros that are optional in C++. */ #include -#if !defined (VBOX_WITH_XPCOM) +#if !defined(VBOX_WITH_XPCOM) -#if defined (RT_OS_WINDOWS) +#if defined(RT_OS_WINDOWS) // Windows COM ///////////////////////////////////////////////////////////////////////////// @@ -88,7 +87,7 @@ #define NS_DECL_ISUPPORTS /** Returns @c true if @a rc represents a warning result code */ -#define SUCCEEDED_WARNING(rc) (SUCCEEDED (rc) && (rc) != S_OK) +#define SUCCEEDED_WARNING(rc) (SUCCEEDED(rc) && (rc) != S_OK) /** Tests is a COM result code indicates that the process implementing the * interface is dead. @@ -96,12 +95,18 @@ * COM status codes: * 0x800706ba - RPC_S_SERVER_UNAVAILABLE. Killed before call was made. * 0x800706be - RPC_S_CALL_FAILED. Killed after call was made. - * 0x800706bf - RPC_S_CALL_FAILED_DNE. Not observed, but should be matter of timing. + * 0x800706bf - RPC_S_CALL_FAILED_DNE. Not observed, but should be + * matter of timing. + * 0x80010108 - RPC_E_DISCONNECTED. Observed deregistering + * python event listener. + * 0x800706b5 - RPC_S_UNKNOWN_IF. Observed deregistering python + * event listener */ #define FAILED_DEAD_INTERFACE(rc) \ ( (rc) == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) \ || (rc) == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED) \ || (rc) == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED_DNE) \ + || (rc) == RPC_E_DISCONNECTED \ ) /** Immutable BSTR string */ @@ -147,7 +152,7 @@ typedef const OLECHAR *CBSTR; /** * Wraps the given parameter name to generate an expression that is suitable for * passing the parameter to functions that take input safearray parameters - * declared using the ComSafeArrayIn marco. + * declared using the ComSafeArrayIn macro. * * @param aArg Parameter name to wrap. The given parameter must be declared * within the calling function using the ComSafeArrayIn macro. @@ -199,13 +204,13 @@ typedef const OLECHAR *CBSTR; * Version of ComSafeArrayInIsNull for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg) +#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull(aArg) /** * Version of ComSafeArrayInArg for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg) +#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg(aArg) /** * Version of ComSafeArrayOut for GUID. @@ -217,13 +222,19 @@ typedef const OLECHAR *CBSTR; * Version of ComSafeArrayOutIsNull for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg) +#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull(aArg) /** * Version of ComSafeArrayOutArg for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg) +#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg(aArg) + +/** + * Gets size of safearray parameter. + * @param aArg Parameter name. + */ +#define ComSafeArraySize(aArg) ((aArg) == NULL ? 0 : (aArg)->rgsabound[0].cElements) /** * Returns the const reference to the IID (i.e., |const GUID &|) of the given @@ -242,18 +253,18 @@ typedef const OLECHAR *CBSTR; */ #define COM_STRUCT_OR_CLASS(I) struct I -#else /* defined (RT_OS_WINDOWS) */ +#else /* defined(RT_OS_WINDOWS) */ #error "VBOX_WITH_XPCOM must be defined on a platform other than Windows!" -#endif /* defined (RT_OS_WINDOWS) */ +#endif /* defined(RT_OS_WINDOWS) */ -#else /* !defined (VBOX_WITH_XPCOM) */ +#else /* !defined(VBOX_WITH_XPCOM) */ // XPCOM ///////////////////////////////////////////////////////////////////////////// -#if defined (RT_OS_DARWIN) || (defined (QT_VERSION) && (QT_VERSION >= 0x040000)) +#if defined(RT_OS_DARWIN) || (defined(QT_VERSION) && (QT_VERSION >= 0x040000)) /* CFBase.h defines these & * qglobal.h from Qt4 defines these */ # undef FALSE @@ -278,7 +289,7 @@ typedef const OLECHAR *CBSTR; #define SUCCEEDED NS_SUCCEEDED #define FAILED NS_FAILED -#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED (rc) && (rc) != NS_OK) +#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED(rc) && (rc) != NS_OK) #define FAILED_DEAD_INTERFACE(rc) ( (rc) == NS_ERROR_ABORT \ || (rc) == NS_ERROR_CALL_FAILED \ @@ -338,20 +349,23 @@ typedef BSTR *LPBSTR; /* safearray input parameter macros for GUID */ #define ComSafeGUIDArrayIn(aArg) PRUint32 aArg##Size, const nsID **aArg -#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg) -#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg) +#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull(aArg) +#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg(aArg) /* safearray output parameter macros for GUID */ #define ComSafeGUIDArrayOut(aArg) PRUint32 *aArg##Size, nsID ***aArg -#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg) -#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg) +#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull(aArg) +#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg(aArg) + +/* safearray size */ +#define ComSafeArraySize(aArg) ((aArg) == NULL ? 0 : (aArg##Size)) /* CLSID and IID for compatibility with Win32 */ typedef nsCID CLSID; typedef nsIID IID; /* OLE error codes */ -#define S_OK ((nsresult) NS_OK) +#define S_OK ((nsresult)NS_OK) #define E_UNEXPECTED NS_ERROR_UNEXPECTED #define E_NOTIMPL NS_ERROR_NOT_IMPLEMENTED #define E_OUTOFMEMORY NS_ERROR_OUT_OF_MEMORY @@ -362,10 +376,11 @@ typedef nsIID IID; #define E_FAIL NS_ERROR_FAILURE /* Note: a better analog for E_ACCESSDENIED would probably be * NS_ERROR_NOT_AVAILABLE, but we want binary compatibility for now. */ -#define E_ACCESSDENIED ((nsresult) 0x80070005L) +#define E_ACCESSDENIED ((nsresult)0x80070005L) #define STDMETHOD(a) NS_IMETHOD a #define STDMETHODIMP NS_IMETHODIMP +#define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth #define COM_IIDOF(I) NS_GET_IID(I) @@ -394,14 +409,14 @@ public: /* helper functions */ extern "C" { -BSTR SysAllocString (const OLECHAR* sz); -BSTR SysAllocStringByteLen (char *psz, unsigned int len); -BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch); -void SysFreeString (BSTR bstr); -int SysReAllocString (BSTR *pbstr, const OLECHAR *psz); -int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch); -unsigned int SysStringByteLen (BSTR bstr); -unsigned int SysStringLen (BSTR bstr); +BSTR SysAllocString(const OLECHAR* sz); +BSTR SysAllocStringByteLen(char *psz, unsigned int len); +BSTR SysAllocStringLen(const OLECHAR *pch, unsigned int cch); +void SysFreeString(BSTR bstr); +int SysReAllocString(BSTR *pbstr, const OLECHAR *psz); +int SysReAllocStringLen(BSTR *pbstr, const OLECHAR *psz, unsigned int cch); +unsigned int SysStringByteLen(BSTR bstr); +unsigned int SysStringLen(BSTR bstr); } /** @@ -443,7 +458,7 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ /** * 'Constructor' that uses an existing getter function that gets a singleton. * The getter function must have the following prototype: - * nsresult _GetterProc (_InstanceClass **inst) + * nsresult _GetterProc(_InstanceClass **inst) * This constructor, as opposed to NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR, * lets the getter function return a result code that is passed back to the * caller that tries to instantiate the object. @@ -481,16 +496,16 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ return rv; \ } -#endif /* !defined (VBOX_WITH_XPCOM) */ +#endif /* !defined(VBOX_WITH_XPCOM) */ /** * Declares a wchar_t string literal from the argument. * Necessary to overcome MSC / GCC differences. * @param s expression to stringify */ -#if defined (_MSC_VER) +#if defined(_MSC_VER) # define WSTR_LITERAL(s) L#s -#elif defined (__GNUC__) +#elif defined(__GNUC__) # define WSTR_LITERAL(s) L""#s #else # error "Unsupported compiler!" @@ -546,4 +561,5 @@ namespace com } /* namespace com */ -#endif /* ___VBox_com_defs_h */ +#endif /* !___VBox_com_defs_h */ + diff --git a/include/VBox/com/errorprint.h b/include/VBox/com/errorprint.h index 2ee11676..f6b49ec0 100644 --- a/include/VBox/com/errorprint.h +++ b/include/VBox/com/errorprint.h @@ -1,11 +1,13 @@ /** @file - * MS COM / XPCOM Abstraction Layer: + * MS COM / XPCOM Abstraction Layer - Error Reporting. + * * Error printing macros using shared functions defined in shared glue code. - * Use these CHECK_* macros for efficient error checking around calling COM methods. + * Use these CHECK_* macros for efficient error checking around calling COM + * methods. */ /* - * 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; @@ -259,3 +261,4 @@ void GlueHandleComErrorProgress(ComPtr progress, if (1) { ASSERT(expr); if (!(expr)) break; } else do {} while (0) } /* namespace com */ + diff --git a/include/VBox/com/list.h b/include/VBox/com/list.h index 11a137b5..5ecf4f16 100644 --- a/include/VBox/com/list.h +++ b/include/VBox/com/list.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -29,8 +29,10 @@ #include #include +#include #include + /** * Specialized list class for using with com::ComPtr * @@ -54,8 +56,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -84,8 +86,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -97,10 +99,10 @@ public: * The class offers methods for importing com::SafeArray's of com::Bstr's. */ template <> -class RTCList: public RTCListBase +class RTCList: public RTCListBase { /* Traits */ - typedef Utf8Str T; + typedef com::Utf8Str T; typedef T *ITYPE; static const bool MT = false; typedef RTCListBase BASE; @@ -114,8 +116,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /** * Creates a copy of another list. @@ -130,9 +132,10 @@ public: RTCList(ComSafeArrayIn(IN_BSTR, other)) { com::SafeArray sfaOther(ComSafeArrayInArg(other)); - realloc(sfaOther.size()); - m_cSize = sfaOther.size(); - for (size_t i = 0; i < m_cSize; ++i) + size_t const cElementsOther = sfaOther.size(); + resizeArray(cElementsOther); + m_cElements = cElementsOther; + for (size_t i = 0; i < cElementsOther; ++i) RTCListHelper::set(m_pArray, i, T(sfaOther[i])); } @@ -147,9 +150,9 @@ public: * @throws std::bad_alloc */ RTCList(const com::SafeArray &other) - : BASE(other.size()) + : BASE(other.size()) { - for (size_t i = 0; i < m_cSize; ++i) + for (size_t i = 0; i < m_cElements; ++i) RTCListHelper::set(m_pArray, i, T(other[i])); } @@ -164,16 +167,19 @@ public: RTCListBase &operator=(const com::SafeArray &other) { m_guard.enterWrite(); + /* Values cleanup */ - RTCListHelper::eraseRange(m_pArray, 0, m_cSize); + RTCListHelper::eraseRange(m_pArray, 0, m_cElements); + /* Copy */ - if (other.size() != m_cCapacity) - realloc_no_elements_clean(other.size()); - m_cSize = other.size(); - for (size_t i = 0; i < other.size(); ++i) + size_t cElementsOther = other.size(); + if (cElementsOther != m_cCapacity) + resizeArrayNoErase(cElementsOther); + m_cElements = cElementsOther; + for (size_t i = 0; i < cElementsOther; ++i) RTCListHelper::set(m_pArray, i, T(other[i])); - m_guard.leaveWrite(); + m_guard.leaveWrite(); return *this; } diff --git a/include/VBox/com/listeners.h b/include/VBox/com/listeners.h index 419b18fa..6a55e4ce 100644 --- a/include/VBox/com/listeners.h +++ b/include/VBox/com/listeners.h @@ -1,6 +1,6 @@ /* $Id: listeners.h $ */ /** @file - * Listeners helpers. + * MS COM / XPCOM Abstraction Layer - Listeners helpers. */ /* @@ -169,3 +169,4 @@ public: #endif #endif + diff --git a/include/VBox/com/mtlist.h b/include/VBox/com/mtlist.h index c4142c5f..16b8e8ce 100644 --- a/include/VBox/com/mtlist.h +++ b/include/VBox/com/mtlist.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -29,6 +29,7 @@ #include #include +#include #include /** @@ -54,8 +55,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -84,7 +85,7 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) : BASE(cCapacity) {} /* Define our own new and delete. */ @@ -97,10 +98,10 @@ public: * The class offers methods for importing com::SafeArray's of com::Bstr's. */ template <> -class RTCMTList: public RTCListBase +class RTCMTList: public RTCListBase { /* Traits */ - typedef Utf8Str T; + typedef com::Utf8Str T; typedef T *ITYPE; static const bool MT = true; typedef RTCListBase BASE; @@ -114,8 +115,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCMTList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /** * Creates a copy of another list. @@ -130,9 +131,10 @@ public: RTCMTList(ComSafeArrayIn(IN_BSTR, other)) { com::SafeArray sfaOther(ComSafeArrayInArg(other)); - realloc(sfaOther.size()); - m_cSize = sfaOther.size(); - for (size_t i = 0; i < m_cSize; ++i) + size_t const cElementsOther = sfaOther.size(); + resizeArray(cElementsOther); + m_cElements = cElementsOther; + for (size_t i = 0; i < cElementsOther; ++i) RTCListHelper::set(m_pArray, i, T(sfaOther[i])); } @@ -149,7 +151,7 @@ public: RTCMTList(const com::SafeArray &other) : BASE(other.size()) { - for (size_t i = 0; i < m_cSize; ++i) + for (size_t i = 0; i < m_cElements; ++i) RTCListHelper::set(m_pArray, i, T(other[i])); } @@ -165,11 +167,11 @@ public: { m_guard.enterWrite(); /* Values cleanup */ - RTCListHelper::eraseRange(m_pArray, 0, m_cSize); + RTCListHelper::eraseRange(m_pArray, 0, m_cElements); /* Copy */ if (other.size() != m_cCapacity) - realloc_no_elements_clean(other.size()); - m_cSize = other.size(); + resizeArrayNoErase(other.size()); + m_cElements = other.size(); for (size_t i = 0; i < other.size(); ++i) RTCListHelper::set(m_pArray, i, T(other[i])); m_guard.leaveWrite(); diff --git a/include/VBox/com/ptr.h b/include/VBox/com/ptr.h index 1942274b..bb6e5715 100644 --- a/include/VBox/com/ptr.h +++ b/include/VBox/com/ptr.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Smart COM pointer classes declaration + * MS COM / XPCOM Abstraction Layer - Smart COM pointer classes declaration. */ /* - * 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; @@ -491,3 +490,4 @@ public: } }; #endif + diff --git a/include/VBox/com/string.h b/include/VBox/com/string.h index 3462818e..63e08ae9 100644 --- a/include/VBox/com/string.h +++ b/include/VBox/com/string.h @@ -204,15 +204,23 @@ public: } bool operator==(const Bstr &that) const { return !compare(that.m_bstr); } + bool operator==(CBSTR that) const { return !compare(that); } + bool operator==(BSTR that) const { return !compare(that); } bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); } - bool operator==(CBSTR that) const { return !compare(that); } - bool operator==(BSTR that) const { return !compare(that); } - - bool operator!=(CBSTR that) const { return !!compare(that); } - bool operator!=(BSTR that) const { return !!compare(that); } - bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; } - bool operator<(CBSTR that) const { return compare(that) < 0; } - bool operator<(BSTR that) const { return compare(that) < 0; } + bool operator!=(CBSTR that) const { return !!compare(that); } + bool operator!=(BSTR that) const { return !!compare(that); } + bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; } + bool operator<(CBSTR that) const { return compare(that) < 0; } + bool operator<(BSTR that) const { return compare(that) < 0; } + bool operator<=(const Bstr &that) const { return compare(that.m_bstr) <= 0; } + bool operator<=(CBSTR that) const { return compare(that) <= 0; } + bool operator<=(BSTR that) const { return compare(that) <= 0; } + bool operator>(const Bstr &that) const { return compare(that.m_bstr) > 0; } + bool operator>(CBSTR that) const { return compare(that) > 0; } + bool operator>(BSTR that) const { return compare(that) > 0; } + bool operator>=(const Bstr &that) const { return compare(that.m_bstr) >= 0; } + bool operator>=(CBSTR that) const { return compare(that) >= 0; } + bool operator>=(BSTR that) const { return compare(that) >= 0; } /** * Returns true if the member string has no length. diff --git a/include/VBox/dbg.h b/include/VBox/dbg.h index 320dac16..7a4a5142 100644 --- a/include/VBox/dbg.h +++ b/include/VBox/dbg.h @@ -7,7 +7,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; @@ -477,7 +477,6 @@ typedef struct DBGCCMDHLP * * @returns VBox status code appropriate to return from a command. * @param pCmdHlp Pointer to the command callback structure. - * @param pVM VM handle if GC or physical HC address. * @param pvBuffer Where to store the read data. * @param cbRead Number of bytes to read. * @param pVarPointer DBGC variable specifying where to start reading. @@ -487,14 +486,13 @@ typedef struct DBGCCMDHLP * If not specified not-present failure or end of a HC physical page * will cause failure. */ - DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead); + DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead); /** * Command helper for writing memory specified by a DBGC variable. * * @returns VBox status code appropriate to return from a command. * @param pCmdHlp Pointer to the command callback structure. - * @param pVM VM handle if GC or physical HC address. * @param pvBuffer What to write. * @param cbWrite Number of bytes to write. * @param pVarPointer DBGC variable specifying where to start reading. @@ -502,7 +500,7 @@ typedef struct DBGCCMDHLP * This is optional. If NULL be aware that some of the buffer * might have been written to the specified address. */ - DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten); + DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten); /** * Executes command an expression. @@ -720,9 +718,9 @@ DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *psz /** * @copydoc FNDBGCHLPMEMREAD */ -DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead) +DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead) { - return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead); + return pCmdHlp->pfnMemRead(pCmdHlp, pvBuffer, cbRead, pVarPointer, pcbRead); } /** @@ -817,9 +815,9 @@ DECLINLINE(int) DBGCCmdHlpParserError(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int i /** Assert+return like macro that the VM handle is present. * Returns with failure if the VM handle is NIL. */ -#define DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM) \ +#define DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM) \ do { \ - if (!(pVM)) \ + if (!(pUVM)) \ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM selected"); \ } while (0) @@ -926,11 +924,11 @@ DECLINLINE(CPUMMODE) DBGCCmdHlpGetCpuMode(PDBGCCMDHLP pCmdHlp) * @returns VBox status. * @param pCmd Pointer to the command descriptor (as registered). * @param pCmdHlp Pointer to command helper functions. - * @param pVM Pointer to the current VM (if any). + * @param pUVM The user mode VM handle, can in theory be NULL. * @param paArgs Pointer to (readonly) array of arguments. * @param cArgs Number of arguments in the array. */ -typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs); +typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs); /** Pointer to a FNDBGCCMD() function. */ typedef FNDBGCCMD *PFNDBGCCMD; @@ -975,12 +973,12 @@ typedef struct DBGCCMD * @returns VBox status. * @param pCmd Pointer to the command descriptor (as registered). * @param pCmdHlp Pointer to command helper functions. - * @param pVM Pointer to the current VM (if any). + * @param pUVM The user mode VM handle, can in theory be NULL. * @param paArgs Pointer to (readonly) array of arguments. * @param cArgs Number of arguments in the array. * @param pResult Where to return the result. */ -typedef DECLCALLBACK(int) FNDBGCFUNC(PCDBGCFUNC pFunc, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, +typedef DECLCALLBACK(int) FNDBGCFUNC(PCDBGCFUNC pFunc, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); /** Pointer to a FNDBGCFUNC() function. */ typedef FNDBGCFUNC *PFNDBGCFUNC; @@ -1091,67 +1089,11 @@ typedef struct DBGCBACK PFNDBGCBACKSETREADY pfnSetReady; } DBGCBACK; - -/** - * Make a console instance. - * - * This will not return until either an 'exit' command is issued or a error code - * indicating connection loss is encountered. - * - * @returns VINF_SUCCESS if console termination caused by the 'exit' command. - * @returns The VBox status code causing the console termination. - * - * @param pVM VM Handle. - * @param pBack Pointer to the backend structure. This must contain - * a full set of function pointers to service the console. - * @param fFlags Reserved, must be zero. - * @remark A forced termination of the console is easiest done by forcing the - * callbacks to return fatal failures. - */ -DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags); - - -/** - * Register one or more external commands. - * - * @returns VBox status. - * @param paCommands Pointer to an array of command descriptors. - * The commands must be unique. It's not possible - * to register the same commands more than once. - * @param cCommands Number of commands. - */ +DBGDECL(int) DBGCCreate(PUVM pUVM, PDBGCBACK pBack, unsigned fFlags); DBGDECL(int) DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands); - - -/** - * Deregister one or more external commands previously registered by - * DBGCRegisterCommands(). - * - * @returns VBox status. - * @param paCommands Pointer to an array of command descriptors - * as given to DBGCRegisterCommands(). - * @param cCommands Number of commands. - */ DBGDECL(int) DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands); - - -/** - * Spawns a new thread with a TCP based debugging console service. - * - * @returns VBox status. - * @param pVM VM handle. - * @param ppvData Where to store the pointer to instance data. - */ -DBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvUser); - -/** - * Terminates any running TCP base debugger console service. - * - * @returns VBox status. - * @param pVM VM handle. - * @param pvData Instance data set by DBGCTcpCreate(). - */ -DBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData); +DBGDECL(int) DBGCTcpCreate(PUVM pUVM, void **ppvUser); +DBGDECL(int) DBGCTcpTerminate(PUVM pUVM, void *pvData); /** @defgroup grp_dbgc_plug_in The DBGC Plug-in Interface @@ -1189,15 +1131,15 @@ typedef enum DBGCPLUGINOP * @returns VBox status code. * * @param enmOperation The operation. - * @param pVM The VM handle. This may be NULL. + * @param pUVM The user mode VM handle. This may be NULL. * @param uArg Extra argument. */ -typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg); +typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg); /** Pointer to a FNDBGCPLUGIN. */ typedef FNDBGCPLUGIN *PFNDBGCPLUGIN; /** @copydoc FNDBGCPLUGIN */ -DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg); +DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg); #endif /* IN_RING3 */ diff --git a/include/VBox/dbggui.h b/include/VBox/dbggui.h index 59a48dc5..5d83557c 100644 --- a/include/VBox/dbggui.h +++ b/include/VBox/dbggui.h @@ -3,7 +3,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; @@ -97,14 +97,14 @@ typedef FNDBGGUICREATE *PFNDBGGUICREATE; * Creates the debugger GUI given a VM handle. * * @returns VBox status code. - * @param pVM The VM handle. + * @param pUVM The VM handle. * @param ppGui Where to store the pointer to the debugger instance. * @param ppGuiVT Where to store the virtual method table pointer. * Optional. */ -DBGDECL(int) DBGGuiCreateForVM(PVM pVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); +DBGDECL(int) DBGGuiCreateForVM(PUVM pUVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); /** @copydoc DBGGuiCreateForVM. */ -typedef DECLCALLBACK(int) FNDBGGUICREATEFORVM(PVM pVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); +typedef DECLCALLBACK(int) FNDBGGUICREATEFORVM(PUVM pUVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); /** Pointer to DBGGuiCreateForVM. */ typedef FNDBGGUICREATEFORVM *PFNDBGGUICREATEFORVM; diff --git a/include/VBox/dbus-calls.h b/include/VBox/dbus-calls.h index 16d2be3d..315be672 100644 --- a/include/VBox/dbus-calls.h +++ b/include/VBox/dbus-calls.h @@ -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; @@ -42,6 +42,8 @@ (DBusBusType type, DBusError *error), (type, error)) \ RT_PROXY_STUB(dbus_error_free, void, (DBusError *error), \ (error)) \ + RT_PROXY_STUB(dbus_free_string_array, void, (char **str_array), \ + (str_array)) \ RT_PROXY_STUB(dbus_connection_unref, void, (DBusConnection *connection), \ (connection)) \ RT_PROXY_STUB(dbus_connection_close, void, (DBusConnection *connection), \ @@ -68,6 +70,12 @@ RT_PROXY_STUB(dbus_message_append_args_valist, dbus_bool_t, \ (DBusMessage *message, int first_arg_type, va_list var_args), \ (message, first_arg_type, var_args)) \ + RT_PROXY_STUB(dbus_message_get_args_valist, dbus_bool_t, \ + (DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args), \ + (message, error, first_arg_type, var_args)) \ + RT_PROXY_STUB(dbus_message_get_type, int, \ + (DBusMessage *message), \ + (message)) \ RT_PROXY_STUB(dbus_message_iter_open_container, dbus_bool_t, \ (DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub), \ (iter, type, contained_signature, sub)) \ @@ -123,7 +131,9 @@ const char *string2), \ (message, string1, string2)) \ RT_PROXY_STUB(dbus_connection_pop_message, DBusMessage *, \ - (DBusConnection *connection), (connection)) + (DBusConnection *connection), (connection)) \ + RT_PROXY_STUB(dbus_set_error_from_message, dbus_bool_t, \ + (DBusError *error, DBusMessage *message), (error, message)) #ifdef VBOX_DBUS_GENERATE_HEADER # define RT_RUNTIME_LOADER_GENERATE_HEADER diff --git a/include/VBox/dbus.h b/include/VBox/dbus.h index 316628f4..468525b8 100644 --- a/include/VBox/dbus.h +++ b/include/VBox/dbus.h @@ -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; @@ -80,14 +80,23 @@ typedef struct DBusMessageIter DBusMessageIter; #define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" -/* Primitive types */ +/* Message types. */ +#define DBUS_MESSAGE_TYPE_INVALID 0 +#define DBUS_MESSAGE_TYPE_METHOD_CALL 1 +#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2 +#define DBUS_MESSAGE_TYPE_ERROR 3 +#define DBUS_MESSAGE_TYPE_SIGNAL 4 + +/* Primitive types. */ #define DBUS_TYPE_INVALID ((int) '\0') +#define DBUS_TYPE_BOOLEAN ((int) 'b') #define DBUS_TYPE_INT32 ((int) 'i') #define DBUS_TYPE_UINT32 ((int) 'u') #define DBUS_TYPE_STRING ((int) 's') #define DBUS_TYPE_STRING_AS_STRING "s" -/* Compound types */ +/* Compound types. */ +#define DBUS_TYPE_OBJECT_PATH ((int) 'o') #define DBUS_TYPE_ARRAY ((int) 'a') #define DBUS_TYPE_ARRAY_AS_STRING "a" #define DBUS_TYPE_DICT_ENTRY ((int) 'e') @@ -112,5 +121,4 @@ typedef void (* DBusFreeFunction) (void *); #undef VBOX_DBUS_GENERATE_HEADER #endif /* ___VBox_DBus_h not defined */ -/* vi: set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/include/VBox/dis.h b/include/VBox/dis.h index 09d8a6ea..01886422 100644 --- a/include/VBox/dis.h +++ b/include/VBox/dis.h @@ -59,7 +59,7 @@ RT_C_DECLS_BEGIN * @{ */ #define DISPREFIX_REX_OP_2_FLAGS(a) (a - OP_PARM_REX_START) -#define DISPREFIX_REX_FLAGS DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX) +/*#define DISPREFIX_REX_FLAGS DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX) - 0, which is no flag */ #define DISPREFIX_REX_FLAGS_B DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_B) #define DISPREFIX_REX_FLAGS_X DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_X) #define DISPREFIX_REX_FLAGS_XB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_XB) @@ -76,6 +76,10 @@ RT_C_DECLS_BEGIN #define DISPREFIX_REX_FLAGS_WRX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRX) #define DISPREFIX_REX_FLAGS_WRXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRXB) /** @} */ +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_B)); +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_X)); +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_W)); +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_R)); /** @name Operand type (DISOPCODE::fOpType). * @{ @@ -106,6 +110,9 @@ RT_C_DECLS_BEGIN #define DISOPTYPE_REXB_EXTENDS_OPREG RT_BIT_32(23) /**< REX.B extends the register field in the opcode byte */ #define DISOPTYPE_MOD_FIXED_11 RT_BIT_32(24) /**< modrm.mod is always 11b */ #define DISOPTYPE_FORCED_32_OP_SIZE_X86 RT_BIT_32(25) /**< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */ +#define DISOPTYPE_SSE RT_BIT_32(29) /**< SSE,SSE2,SSE3,AVX,++ instruction. Not implemented yet! */ +#define DISOPTYPE_MMX RT_BIT_32(30) /**< MMX,MMXExt,3DNow,++ instruction. Not implemented yet! */ +#define DISOPTYPE_FPU RT_BIT_32(31) /**< FPU instruction. Not implemented yet! */ #define DISOPTYPE_ALL UINT32_C(0xffffffff) /** @} */ diff --git a/include/VBox/disopcode.h b/include/VBox/disopcode.h index c83f5052..22ca0909 100644 --- a/include/VBox/disopcode.h +++ b/include/VBox/disopcode.h @@ -292,7 +292,7 @@ #define OP_PSRLQ 244 #define OP_PADDQ 245 #define OP_PMULLW 246 -#define OP_PMOVSKB 247 +#define OP_PMOVMSKB 247 #define OP_PSUBUSB 248 #define OP_PSUBUSW 249 #define OP_PMINUB 250 diff --git a/include/VBox/err.h b/include/VBox/err.h index 3fae9bc9..ef999408 100644 --- a/include/VBox/err.h +++ b/include/VBox/err.h @@ -3,7 +3,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; @@ -84,6 +84,8 @@ * Returned by pfnInit in VBoxService to indicated a non-fatal error that * should results in the particular service being disabled. */ #define VERR_SERVICE_DISABLED (-1020) +/** The requested feature is not supported in raw-mode. */ +#define VERR_NOT_SUP_IN_RAW_MODE (-1021) /** @} */ @@ -156,7 +158,7 @@ #define VINF_EM_RESCHEDULE_REM 1115 /** Indicating that a rescheduling to vmx-mode execution. * Typically caused by REM detecting that hardware-accelerated raw-mode execution is possible. */ -#define VINF_EM_RESCHEDULE_HWACC 1116 +#define VINF_EM_RESCHEDULE_HM 1116 /** Indicating that a rescheduling to raw-mode execution. * Typically caused by REM detecting that raw-mode execution is possible. * @remarks Important to have a higher priority (lower number) than VINF_EM_RESCHEDULE. */ @@ -235,12 +237,15 @@ /** Start instruction stepping (debug only). */ #define VINF_EM_RAW_EMULATE_DBG_STEP 1151 /** Patch TPR access instruction. */ -#define VINF_EM_HWACCM_PATCH_TPR_INSTR 1152 -/** The EMInterpretDisasOne / EMInterpretDisasOneEx methods failed to - * disassemble the instruction. */ -#define VERR_EM_INTERNAL_DISAS_ERROR (-1153) +#define VINF_EM_HM_PATCH_TPR_INSTR 1152 /** Unexpected guest mapping conflict detected. */ #define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154) +/** Reason for leaving RC: A triple-fault condition. Currently, causes + * a guru meditation. */ +#define VINF_EM_TRIPLE_FAULT 1155 +/** The specified execution engine cannot execute guest code in the current + * state. */ +#define VERR_EM_CANNOT_EXEC_GUEST (-1156) /** @} */ @@ -360,6 +365,8 @@ #define VINF_PATM_SPINLOCK_FAILED (1429) /** Continue execution after patch trap. */ #define VINF_PATCH_CONTINUE (1430) +/** The patch manager is not used because we're using HM and VT-x/AMD-V. */ +#define VERR_PATM_HM_IPE (-1431) /** @} */ @@ -375,6 +382,8 @@ #define VWRN_CSAM_PAGE_NOT_FOUND 1502 /** Reason for leaving RC: CSAM wants perform a task in ring-3. */ #define VINF_CSAM_PENDING_ACTION 1503 +/** The CSAM is not used because we're using HM and VT-x/AMD-V. */ +#define VERR_CSAM_HM_IPE (-1504) /** @} */ @@ -570,6 +579,11 @@ #define VERR_PGM_PHYS_NULL_PAGE_PARAM (-1681) /** PCI passthru is not supported by this build. */ #define VERR_PGM_PCI_PASSTHRU_MISCONFIG (-1682) +/** Too many MMIO2 ranges. */ +#define VERR_PGM_TOO_MANY_MMIO2_RANGES (-1683) +/** Internal processing error in the PGM physial page mapping code dealing + * with MMIO2 pages. */ +#define VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE (-1684) /** @} */ @@ -596,6 +610,16 @@ /** CPUMR3DisasmInstrCPU unexpectedly failed to determin the hidden * parts of the CS register. */ #define VERR_CPUM_HIDDEN_CS_LOAD_ERROR (-1752) +/** Couldn't find the end of CPUID sub-leaves. */ +#define VERR_CPUM_TOO_MANY_CPUID_SUBLEAVES (-1753) +/** CPUM internal processing error \#1. */ +#define VERR_CPUM_IPE_1 (-1754) +/** CPUM internal processing error \#2. */ +#define VERR_CPUM_IPE_2 (-1755) +/** The specified CPU cannot be found in the CPU database. */ +#define VERR_CPUM_DB_CPU_NOT_FOUND (-1756) +/** Invalid CPUMCPU offset in MSR range. */ +#define VERR_CPUM_MSR_BAD_CPUMCPU_OFFSET (-1757) /** @} */ @@ -968,6 +992,8 @@ #define VERR_TRPM_IPE_2 (-2408) /** Internal processing error \#3 in TRPM. */ #define VERR_TRPM_IPE_3 (-2409) +/** Got into a part of TRPM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_TRPM_HM_IPE (-2410) /** @} */ @@ -999,6 +1025,8 @@ /** The guest GDT so full that we cannot find free space for our own * selectors. */ #define VERR_SELM_GDT_TOO_FULL (-2508) +/** Got into a part of SELM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_SELM_HM_IPE (-2509) /** @} */ @@ -1078,6 +1106,8 @@ #define VERR_IOM_MMIO_IPE_2 (-2635) /** Internal processing error \#3 in the MMIO code. */ #define VERR_IOM_MMIO_IPE_3 (-2636) +/** Got into a part of IOM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_IOM_HM_IPE (-2637) /** @} */ @@ -1117,6 +1147,12 @@ #define VINF_VMM_CALL_TRACER (2712) /** Internal processing error \#1 in the switcher code. */ #define VERR_VMM_SWITCHER_IPE_1 (-2713) +/** Reason for leaving RZ: Unknown call to ring-3. */ +#define VINF_VMM_UNKNOWN_RING3_CALL (2714) +/** Attempted to use stub switcher. */ +#define VERR_VMM_SWITCHER_STUB (-2715) +/** HM returned in the wrong state. */ +#define VERR_VMM_WRONG_HM_VMCPU_STATE (-2716) /** @} */ @@ -1224,13 +1260,9 @@ /** No PCI Bus is available to register the device with. This is usually a * misconfiguration or in rare cases a buggy pci device. */ #define VERR_PDM_NO_PCI_BUS (-2833) -/** PCI physical read with bus mastering disabled. */ -#define VINF_PDM_PCI_PHYS_READ_BM_DISABLED (2833) /** The device is not a registered PCI device and thus cannot * perform any PCI operations. The device forgot to register it self. */ #define VERR_PDM_NOT_PCI_DEVICE (-2834) -/** PCI physical write with bus mastering disabled. */ -#define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED (2834) /** The version of the device registration structure is unknown * to this VBox version. Either mixing incompatible versions or @@ -1398,6 +1430,11 @@ /** The driver is already removed, not more transformations possible (at * present). */ #define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER (-2890) +/** The PCI device isn't configured as a busmaster, physical memory access + * rejected. */ +#define VERR_PDM_NOT_PCI_BUS_MASTER (-2891) +/** Got into a part of PDM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_PDM_HM_IPE (-2892) /** @} */ @@ -1554,6 +1591,10 @@ #define VERR_VD_READ_OUT_OF_RANGE (-3282) /** Block read was marked as free in the image and returned as a zero block. */ #define VINF_VD_NEW_ZEROED_BLOCK 3283 +/** Unable to parse the XML in DMG file. */ +#define VERR_VD_DMG_XML_PARSE_ERROR (-3284) +/** Unable to locate a usable DMG file within the XAR archive. */ +#define VERR_VD_DMG_NOT_FOUND_INSIDE_XAR (-3285) /** @} */ @@ -1851,44 +1892,64 @@ /** @name VBox VMX Status Codes * @{ */ -/** Invalid VMCS index or write to read-only element. */ -#define VERR_VMX_INVALID_VMCS_FIELD (-4000) -/** Invalid VMCS pointer. */ +/** VMXON failed; possibly because it was already run before. */ +#define VERR_VMX_VMXON_FAILED (-4000) +/** Invalid VMCS pointer. + * (Can be OR'ed with VERR_VMX_INVALID_VMCS_FIELD.) */ #define VERR_VMX_INVALID_VMCS_PTR (-4001) +/** Invalid VMCS index or write to read-only element. */ +#define VERR_VMX_INVALID_VMCS_FIELD (-4002) +/** Reserved for future status code that we wish to OR with + * VERR_VMX_INVALID_VMCS_PTR and VERR_VMX_INVALID_VMCS_FIELD. */ +#define VERR_VMX_RESERVED (-4003) /** Invalid VMXON pointer. */ -#define VERR_VMX_INVALID_VMXON_PTR (-4002) -/** Generic VMX failure. */ -#define VERR_VMX_GENERIC (-4003) -/** Invalid CPU mode for VMX execution. */ -#define VERR_VMX_UNSUPPORTED_MODE (-4004) +#define VERR_VMX_INVALID_VMXON_PTR (-4004) /** Unable to start VM execution. */ #define VERR_VMX_UNABLE_TO_START_VM (-4005) -/** Unable to resume VM execution. */ -#define VERR_VMX_UNABLE_TO_RESUME_VM (-4006) /** Unable to switch due to invalid host state. */ -#define VERR_VMX_INVALID_HOST_STATE (-4007) +#define VERR_VMX_INVALID_HOST_STATE (-4006) /** IA32_FEATURE_CONTROL MSR not setup correcty (turn on VMX in the host system BIOS) */ -#define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4008) +#define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4007) +/** Invalid CPU mode for VMX execution. */ +#define VERR_VMX_UNSUPPORTED_MODE (-4008) /** VMX CPU extension not available */ #define VERR_VMX_NO_VMX (-4009) -/** VMXON failed; possibly because it was already run before */ -#define VERR_VMX_VMXON_FAILED (-4010) /** CPU was incorrectly left in VMX root mode; incompatible with VirtualBox */ #define VERR_VMX_IN_VMX_ROOT_MODE (-4011) /** Somebody cleared X86_CR4_VMXE in the CR4 register. */ #define VERR_VMX_X86_CR4_VMXE_CLEARED (-4012) -/** VT-x features locked or unavailable in MSR. */ -#define VERR_VMX_MSR_LOCKED_OR_DISABLED (-4013) +/** Failed to enable and lock VT-x features. */ +#define VERR_VMX_MSR_LOCKING_FAILED (-4013) /** Unable to switch due to invalid guest state. */ #define VERR_VMX_INVALID_GUEST_STATE (-4014) -/** Unexpected VM exit code. */ -#define VERR_VMX_UNEXPECTED_EXIT_CODE (-4015) -/** Unexpected VM exception code. */ +/** Unexpected VM exit. */ +#define VERR_VMX_UNEXPECTED_EXIT (-4015) +/** Unexpected VM exception. */ #define VERR_VMX_UNEXPECTED_EXCEPTION (-4016) -/** Unexpected interruption exit code. */ -#define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE (-4017) -/** CPU is not in VMX root mode; unexpected when leaving VMX root mode */ +/** Unexpected interruption exit type. */ +#define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE (-4017) +/** CPU is not in VMX root mode; unexpected when leaving VMX root mode. */ #define VERR_VMX_NOT_IN_VMX_ROOT_MODE (-4018) +/** Undefined VM exit code. */ +#define VERR_VMX_UNDEFINED_EXIT_CODE (-4019) +/** VMPTRLD failed; possibly because of invalid VMCS launch-state. */ +#define VERR_VMX_VMPTRLD_FAILED (-4021) +/** Invalid VMCS pointer passed to VMLAUNCH/VMRESUME. */ +#define VERR_VMX_INVALID_VMCS_PTR_TO_START_VM (-4022) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_1 (-4023) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_2 (-4024) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_3 (-4025) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_4 (-4026) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_5 (-4027) +/** VT-x features for SMX operation disabled by the BIOS. */ +#define VERR_VMX_MSR_SMX_VMXON_DISABLED (-4028) +/** VT-x features disabled by the BIOS. */ +#define VERR_VMX_MSR_VMXON_DISABLED (-4029) /** @} */ @@ -1905,44 +1966,60 @@ #define VERR_SVM_DISABLED (-4053) /** AMD-V CPU extension in-use. */ #define VERR_SVM_IN_USE (-4054) +/** Invalid pVMCB. */ +#define VERR_SVM_INVALID_PVMCB (-4055) +/** Unexpected SVM exit. */ +#define VERR_SVM_UNEXPECTED_EXIT (-4056) +/** Unexpected SVM exception exit. */ +#define VERR_SVM_UNEXPECTED_XCPT_EXIT (-4057) +/** Unexpected SVM patch type. */ +#define VERR_SVM_UNEXPECTED_PATCH_TYPE (-4058) +/** Unable to start VM execution due to an invalid guest state. */ +#define VERR_SVM_INVALID_GUEST_STATE (-4059) +/** Unknown or unrecognized SVM exit. */ +#define VERR_SVM_UNKNOWN_EXIT (-4060) /** @} */ -/** @name VBox HWACCM Status Codes +/** @name VBox HM Status Codes * @{ */ /** Unable to start VM execution. */ -#define VERR_HWACCM_UNKNOWN_CPU (-4100) +#define VERR_HM_UNKNOWN_CPU (-4100) /** No CPUID support. */ -#define VERR_HWACCM_NO_CPUID (-4101) +#define VERR_HM_NO_CPUID (-4101) /** Host is about to go into suspend mode. */ -#define VERR_HWACCM_SUSPEND_PENDING (-4102) +#define VERR_HM_SUSPEND_PENDING (-4102) /** Conflicting CFGM values. */ -#define VERR_HWACCM_CONFIG_MISMATCH (-4103) +#define VERR_HM_CONFIG_MISMATCH (-4103) /** Internal processing error in the HM init code. */ #define VERR_HM_ALREADY_ENABLED_IPE (-4104) /** Unexpected MSR in the load / restore list. */ #define VERR_HM_UNEXPECTED_LD_ST_MSR (-4105) /** No 32-bit to 64-bit switcher in place. */ #define VERR_HM_NO_32_TO_64_SWITCHER (-4106) -/** Invalid pVMCB. */ -#define VERR_HMSVM_INVALID_PVMCB (-4107) -/** Unexpected SVM exit. */ -#define VERR_HMSVM_UNEXPECTED_EXIT (-4108) -/** Unexpected SVM exception exit. */ -#define VERR_HMSVM_UNEXPECTED_XCPT_EXIT (-4109) -/** Unexpected SVM patch type. */ -#define VERR_HMSVM_UNEXPECTED_PATCH_TYPE (-4110) -/** HWACCMR0Leave was called on the wrong CPU. */ -#define VERR_HM_WRONG_CPU_1 (-4111) +/** HMR0Leave was called on the wrong CPU. */ +#define VERR_HM_WRONG_CPU_1 (-4107) /** Internal processing error \#1 in the HM code. */ -#define VERR_HM_IPE_1 (-4112) +#define VERR_HM_IPE_1 (-4108) /** Internal processing error \#2 in the HM code. */ -#define VERR_HM_IPE_2 (-4113) +#define VERR_HM_IPE_2 (-4109) /** Wrong 32/64-bit switcher. */ -#define VERR_HM_WRONG_SWITCHER (-4114) +#define VERR_HM_WRONG_SWITCHER (-4110) /** Unknown I/O instruction. */ -#define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4115) +#define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4111) +/** Unsupported CPU feature combination. */ +#define VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO (-4112) +/** Internal processing error \#3 in the HM code. */ +#define VERR_HM_IPE_3 (-4113) +/** Internal processing error \#3 in the HM code. */ +#define VERR_HM_IPE_4 (-4114) +/** Internal processing error \#3 in the HM code. */ +#define VERR_HM_IPE_5 (-4115) +/** Invalid HM64ON32OP value. */ +#define VERR_HM_INVALID_HM64ON32OP (-4116) +/** Resume guest execution after injecting a double-fault. */ +#define VINF_HM_DOUBLE_FAULT 4117 /** @} */ @@ -1959,8 +2036,6 @@ #define VERR_DIS_INVALID_MODRM (-4203) /** Invalid parameter index. */ #define VERR_DIS_INVALID_PARAMETER (-4204) -/** Reading opcode bytes failed. */ -#define VERR_DIS_MEM_READ (-4205) /** The instruction is too long. */ #define VERR_DIS_TOO_LONG_INSTR (-4206) /** @} */ @@ -2090,7 +2165,7 @@ #define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC (-5100) /** VT-x/AMD-V not active. * PCI passthrough currently works only if VT-x/AMD-V is active. */ -#define VERR_PCI_PASSTHROUGH_NO_HWACCM (-5101) +#define VERR_PCI_PASSTHROUGH_NO_HM (-5101) /** Nested paging not active. * PCI passthrough currently works only if nested paging is active. */ #define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING (-5102) @@ -2117,6 +2192,17 @@ * @{ */ /** The instruction is not yet implemented by IEM. */ #define VERR_IEM_INSTR_NOT_IMPLEMENTED (-5300) +/** Invalid operand size passed to an IEM function. */ +#define VERR_IEM_INVALID_OPERAND_SIZE (-5301) +/** Invalid address mode passed to an IEM function. */ +#define VERR_IEM_INVALID_ADDRESS_MODE (-5302) +/** Invalid effective segment register number passed to an IEM function. */ +#define VERR_IEM_INVALID_EFF_SEG (-5303) +/** Invalid instruction length passed to an IEM function. */ +#define VERR_IEM_INVALID_INSTR_LENGTH (-5304) +/** Internal status code for indicating that a selector isn't valid (LAR, LSL, + * VERR, VERW). This is not used outside the instruction implementations. */ +#define VINF_IEM_SELECTOR_NOT_OK (5305) /** This particular aspect of the instruction is not yet implemented by IEM. */ #define VERR_IEM_ASPECT_NOT_IMPLEMENTED (-5391) /** Internal processing error \#1 in the IEM code.. */ @@ -2224,6 +2310,18 @@ /** @} */ +/** @} */ + +/** @name VBox Guest Control Status Codes + * @{ + */ +/** Guest side reported an error. */ +#define VERR_GSTCTL_GUEST_ERROR (-6200) +/** A guest control object has changed its overall status. */ +#define VWRN_GSTCTL_OBJECTSTATE_CHANGED 6220 +/** @} */ + + /* SED-END */ /** @} */ diff --git a/include/VBox/err.mac b/include/VBox/err.mac index 2470d6c0..ac39b103 100644 --- a/include/VBox/err.mac +++ b/include/VBox/err.mac @@ -19,6 +19,7 @@ %define VERR_INVALID_CPU_ID (-1018) %define VERR_TOO_MANY_CPUS (-1019) %define VERR_SERVICE_DISABLED (-1020) +%define VERR_NOT_SUP_IN_RAW_MODE (-1021) %define VINF_EM_FIRST 1100 %define VINF_EM_TERMINATE 1100 %define VINF_EM_DBG_HYPER_STEPPED 1101 @@ -36,7 +37,7 @@ %define VINF_EM_NO_MEMORY 1114 %define VERR_EM_NO_MEMORY (-1114) %define VINF_EM_RESCHEDULE_REM 1115 -%define VINF_EM_RESCHEDULE_HWACC 1116 +%define VINF_EM_RESCHEDULE_HM 1116 %define VINF_EM_RESCHEDULE_RAW 1117 %define VINF_EM_RESCHEDULE 1118 %define VINF_EM_RESCHEDULE_PARAV 1119 @@ -66,9 +67,10 @@ %define VERR_EM_INTERNAL_ERROR (-1149) %define VINF_EM_PENDING_REQUEST 1150 %define VINF_EM_RAW_EMULATE_DBG_STEP 1151 -%define VINF_EM_HWACCM_PATCH_TPR_INSTR 1152 -%define VERR_EM_INTERNAL_DISAS_ERROR (-1153) +%define VINF_EM_HM_PATCH_TPR_INSTR 1152 %define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154) +%define VINF_EM_TRIPLE_FAULT 1155 +%define VERR_EM_CANNOT_EXEC_GUEST (-1156) %define VERR_DBGF_NOT_ATTACHED (-1200) %define VERR_DBGF_ALREADY_ATTACHED (-1201) %define VWRN_DBGF_ALREADY_HALTED 1202 @@ -118,10 +120,12 @@ %define VERR_PATM_ALREADY_PATCHED (-1428) %define VINF_PATM_SPINLOCK_FAILED (1429) %define VINF_PATCH_CONTINUE (1430) +%define VERR_PATM_HM_IPE (-1431) %define VWRN_CSAM_TRAP_NOT_HANDLED 1500 %define VWRN_CSAM_INSTRUCTION_PATCHED 1501 %define VWRN_CSAM_PAGE_NOT_FOUND 1502 %define VINF_CSAM_PENDING_ACTION 1503 +%define VERR_CSAM_HM_IPE (-1504) %define VERR_PGM_MAPPING_CONFLICT (-1600) %define VERR_PGM_HANDLER_PHYSICAL_NO_RAM_RANGE (-1601) %define VERR_PGM_HANDLER_VIRTUAL_CONFLICT (-1602) @@ -203,12 +207,19 @@ %define VERR_PGM_PHYS_PAGE_GET_IPE (-1680) %define VERR_PGM_PHYS_NULL_PAGE_PARAM (-1681) %define VERR_PGM_PCI_PASSTHRU_MISCONFIG (-1682) +%define VERR_PGM_TOO_MANY_MMIO2_RANGES (-1683) +%define VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE (-1684) %define VERR_MM_RAM_CONFLICT (-1700) %define VERR_MM_HYPER_NO_MEMORY (-1701) %define VERR_MM_BAD_TRAP_TYPE_IPE (-1702) %define VERR_CPUM_RAISE_GP_0 (-1750) %define VERR_CPUM_INCOMPATIBLE_CONFIG (-1751) %define VERR_CPUM_HIDDEN_CS_LOAD_ERROR (-1752) +%define VERR_CPUM_TOO_MANY_CPUID_SUBLEAVES (-1753) +%define VERR_CPUM_IPE_1 (-1754) +%define VERR_CPUM_IPE_2 (-1755) +%define VERR_CPUM_DB_CPU_NOT_FOUND (-1756) +%define VERR_CPUM_MSR_BAD_CPUMCPU_OFFSET (-1757) %define VERR_SSM_UNIT_EXISTS (-1800) %define VERR_SSM_UNIT_NOT_FOUND (-1801) %define VERR_SSM_UNIT_NOT_OWNER (-1802) @@ -355,6 +366,7 @@ %define VERR_TRPM_IPE_1 (-2407) %define VERR_TRPM_IPE_2 (-2408) %define VERR_TRPM_IPE_3 (-2409) +%define VERR_TRPM_HM_IPE (-2410) %define VERR_SELM_SHADOW_GDT_WRITE (-2500) %define VERR_SELM_SHADOW_LDT_WRITE (-2501) %define VERR_SELM_SHADOW_TSS_WRITE (-2502) @@ -364,6 +376,7 @@ %define VERR_SELM_LDT_OUT_OF_BOUNDS (-2506) %define VERR_SELM_GDT_READ_ERROR (-2507) %define VERR_SELM_GDT_TOO_FULL (-2508) +%define VERR_SELM_HM_IPE (-2509) %define VERR_IOM_INVALID_IOPORT_RANGE (-2600) %define VERR_IOM_NO_R3_IOPORT_RANGE (-2601) %define VERR_IOM_IOPORT_RANGE_CONFLICT (-2602) @@ -393,6 +406,7 @@ %define VERR_IOM_MMIO_IPE_1 (-2634) %define VERR_IOM_MMIO_IPE_2 (-2635) %define VERR_IOM_MMIO_IPE_3 (-2636) +%define VERR_IOM_HM_IPE (-2637) %define VINF_VMM_CALL_HOST 2700 %define VERR_VMM_RING0_ASSERTION (-2701) %define VERR_VMM_HYPER_CR3_MISMATCH (-2702) @@ -407,6 +421,9 @@ %define VERR_VMM_RING3_CALL_NO_RC (-2711) %define VINF_VMM_CALL_TRACER (2712) %define VERR_VMM_SWITCHER_IPE_1 (-2713) +%define VINF_VMM_UNKNOWN_RING3_CALL (2714) +%define VERR_VMM_SWITCHER_STUB (-2715) +%define VERR_VMM_WRONG_HM_VMCPU_STATE (-2716) %define VERR_PDM_NO_SUCH_LUN (-2800) %define VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES (-2801) %define VERR_PDM_MISSING_INTERFACE_ABOVE (-2802) @@ -441,9 +458,7 @@ %define VERR_PDM_INVALID_DRIVER_HOST_BITS (-2831) %define VERR_PDM_DRIVER_DETACH_NOT_POSSIBLE (-2832) %define VERR_PDM_NO_PCI_BUS (-2833) -%define VINF_PDM_PCI_PHYS_READ_BM_DISABLED (2833) %define VERR_PDM_NOT_PCI_DEVICE (-2834) -%define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED (2834) %define VERR_PDM_UNKNOWN_DEVREG_VERSION (-2835) %define VERR_PDM_INVALID_DEVICE_REGISTRATION (-2836) %define VERR_PDM_INVALID_DEVICE_GUEST_BITS (-2837) @@ -501,6 +516,8 @@ %define VERR_PDM_DEV_IPE_1 (-2888) %define VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION (-2889) %define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER (-2890) +%define VERR_PDM_NOT_PCI_BUS_MASTER (-2891) +%define VERR_PDM_HM_IPE (-2892) %define VERR_HGCM_SERVICE_NOT_FOUND (-2900) %define VINF_HGCM_CLIENT_REJECTED 2901 %define VERR_HGCM_INVALID_CMD_ADDRESS (-2902) @@ -564,6 +581,8 @@ %define VERR_VD_IMAGE_REPAIR_IMPOSSIBLE (-3281) %define VERR_VD_READ_OUT_OF_RANGE (-3282) %define VINF_VD_NEW_ZEROED_BLOCK 3283 +%define VERR_VD_DMG_XML_PARSE_ERROR (-3284) +%define VERR_VD_DMG_NOT_FOUND_INSIDE_XAR (-3285) %define VERR_VBGL_NOT_INITIALIZED (-3300) %define VERR_VBGL_INVALID_ADDR (-3301) %define VERR_VBGL_IOCTL_FAILED (-3302) @@ -678,52 +697,68 @@ %define VINF_GVM_NOT_BLOCKED 3901 %define VINF_GVM_NOT_BUSY_IN_GC 3902 %define VINF_GVM_YIELDED 3903 -%define VERR_VMX_INVALID_VMCS_FIELD (-4000) +%define VERR_VMX_VMXON_FAILED (-4000) %define VERR_VMX_INVALID_VMCS_PTR (-4001) -%define VERR_VMX_INVALID_VMXON_PTR (-4002) -%define VERR_VMX_GENERIC (-4003) -%define VERR_VMX_UNSUPPORTED_MODE (-4004) +%define VERR_VMX_INVALID_VMCS_FIELD (-4002) +%define VERR_VMX_RESERVED (-4003) +%define VERR_VMX_INVALID_VMXON_PTR (-4004) %define VERR_VMX_UNABLE_TO_START_VM (-4005) -%define VERR_VMX_UNABLE_TO_RESUME_VM (-4006) -%define VERR_VMX_INVALID_HOST_STATE (-4007) -%define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4008) +%define VERR_VMX_INVALID_HOST_STATE (-4006) +%define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4007) +%define VERR_VMX_UNSUPPORTED_MODE (-4008) %define VERR_VMX_NO_VMX (-4009) -%define VERR_VMX_VMXON_FAILED (-4010) %define VERR_VMX_IN_VMX_ROOT_MODE (-4011) %define VERR_VMX_X86_CR4_VMXE_CLEARED (-4012) -%define VERR_VMX_MSR_LOCKED_OR_DISABLED (-4013) +%define VERR_VMX_MSR_LOCKING_FAILED (-4013) %define VERR_VMX_INVALID_GUEST_STATE (-4014) -%define VERR_VMX_UNEXPECTED_EXIT_CODE (-4015) +%define VERR_VMX_UNEXPECTED_EXIT (-4015) %define VERR_VMX_UNEXPECTED_EXCEPTION (-4016) -%define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE (-4017) +%define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE (-4017) %define VERR_VMX_NOT_IN_VMX_ROOT_MODE (-4018) +%define VERR_VMX_UNDEFINED_EXIT_CODE (-4019) +%define VERR_VMX_VMPTRLD_FAILED (-4021) +%define VERR_VMX_INVALID_VMCS_PTR_TO_START_VM (-4022) +%define VERR_HMVMX_IPE_1 (-4023) +%define VERR_HMVMX_IPE_2 (-4024) +%define VERR_HMVMX_IPE_3 (-4025) +%define VERR_HMVMX_IPE_4 (-4026) +%define VERR_HMVMX_IPE_5 (-4027) +%define VERR_VMX_MSR_SMX_VMXON_DISABLED (-4028) +%define VERR_VMX_MSR_VMXON_DISABLED (-4029) %define VERR_SVM_UNABLE_TO_START_VM (-4050) %define VERR_SVM_ILLEGAL_EFER_MSR (-4051) %define VERR_SVM_NO_SVM (-4052) %define VERR_SVM_DISABLED (-4053) %define VERR_SVM_IN_USE (-4054) -%define VERR_HWACCM_UNKNOWN_CPU (-4100) -%define VERR_HWACCM_NO_CPUID (-4101) -%define VERR_HWACCM_SUSPEND_PENDING (-4102) -%define VERR_HWACCM_CONFIG_MISMATCH (-4103) +%define VERR_SVM_INVALID_PVMCB (-4055) +%define VERR_SVM_UNEXPECTED_EXIT (-4056) +%define VERR_SVM_UNEXPECTED_XCPT_EXIT (-4057) +%define VERR_SVM_UNEXPECTED_PATCH_TYPE (-4058) +%define VERR_SVM_INVALID_GUEST_STATE (-4059) +%define VERR_SVM_UNKNOWN_EXIT (-4060) +%define VERR_HM_UNKNOWN_CPU (-4100) +%define VERR_HM_NO_CPUID (-4101) +%define VERR_HM_SUSPEND_PENDING (-4102) +%define VERR_HM_CONFIG_MISMATCH (-4103) %define VERR_HM_ALREADY_ENABLED_IPE (-4104) %define VERR_HM_UNEXPECTED_LD_ST_MSR (-4105) %define VERR_HM_NO_32_TO_64_SWITCHER (-4106) -%define VERR_HMSVM_INVALID_PVMCB (-4107) -%define VERR_HMSVM_UNEXPECTED_EXIT (-4108) -%define VERR_HMSVM_UNEXPECTED_XCPT_EXIT (-4109) -%define VERR_HMSVM_UNEXPECTED_PATCH_TYPE (-4110) -%define VERR_HM_WRONG_CPU_1 (-4111) -%define VERR_HM_IPE_1 (-4112) -%define VERR_HM_IPE_2 (-4113) -%define VERR_HM_WRONG_SWITCHER (-4114) -%define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4115) +%define VERR_HM_WRONG_CPU_1 (-4107) +%define VERR_HM_IPE_1 (-4108) +%define VERR_HM_IPE_2 (-4109) +%define VERR_HM_WRONG_SWITCHER (-4110) +%define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4111) +%define VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO (-4112) +%define VERR_HM_IPE_3 (-4113) +%define VERR_HM_IPE_4 (-4114) +%define VERR_HM_IPE_5 (-4115) +%define VERR_HM_INVALID_HM64ON32OP (-4116) +%define VINF_HM_DOUBLE_FAULT 4117 %define VERR_DIS_INVALID_OPCODE (-4200) %define VERR_DIS_GEN_FAILURE (-4201) %define VERR_DIS_NO_READ_CALLBACK (-4202) %define VERR_DIS_INVALID_MODRM (-4203) %define VERR_DIS_INVALID_PARAMETER (-4204) -%define VERR_DIS_MEM_READ (-4205) %define VERR_DIS_TOO_LONG_INSTR (-4206) %define VERR_WEB_NOT_AUTHENTICATED (-4300) %define VERR_WEB_INVALID_MANAGED_OBJECT_REFERENCE (-4301) @@ -759,7 +794,7 @@ %define VERR_FAM_MONITOR_DIRECTORY_FAILED (-5002) %define VERR_FAM_CONNECTION_LOST (-5003) %define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC (-5100) -%define VERR_PCI_PASSTHROUGH_NO_HWACCM (-5101) +%define VERR_PCI_PASSTHROUGH_NO_HM (-5101) %define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING (-5102) %define VERR_GVMM_INSTANCE (-5200) %define VERR_GVMM_HOST_CPU_RANGE (-5201) @@ -767,6 +802,11 @@ %define VERR_GVMM_IPE_1 (-5203) %define VERR_GVMM_IPE_2 (-5204) %define VERR_IEM_INSTR_NOT_IMPLEMENTED (-5300) +%define VERR_IEM_INVALID_OPERAND_SIZE (-5301) +%define VERR_IEM_INVALID_ADDRESS_MODE (-5302) +%define VERR_IEM_INVALID_EFF_SEG (-5303) +%define VERR_IEM_INVALID_INSTR_LENGTH (-5304) +%define VINF_IEM_SELECTOR_NOT_OK (5305) %define VERR_IEM_ASPECT_NOT_IMPLEMENTED (-5391) %define VERR_IEM_IPE_1 (-5392) %define VERR_IEM_IPE_2 (-5393) @@ -809,4 +849,6 @@ %define VERR_DBGC_PARSE_BUG (VERR_DBGC_PARSE_LOWEST + 25) %define VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL (-6000) %define VERR_EXTPACK_VBOX_VERSION_MISMATCH (-6001) +%define VERR_GSTCTL_GUEST_ERROR (-6200) +%define VWRN_GSTCTL_OBJECTSTATE_CHANGED 6220 %include "iprt/err.mac" diff --git a/include/VBox/err.sed b/include/VBox/err.sed index b9c18489..52bb3626 100644 --- a/include/VBox/err.sed +++ b/include/VBox/err.sed @@ -3,7 +3,7 @@ # SED script for converting VBox/err.h to .mac. # -# Copyright (C) 2006-2009 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/include/VBox/hgcmsvc.h b/include/VBox/hgcmsvc.h index c3480a73..9442bb7d 100644 --- a/include/VBox/hgcmsvc.h +++ b/include/VBox/hgcmsvc.h @@ -3,7 +3,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/include/VBox/intnet.h b/include/VBox/intnet.h index dc439ea5..e032baf1 100644 --- a/include/VBox/intnet.h +++ b/include/VBox/intnet.h @@ -213,11 +213,11 @@ typedef INTNETIFHANDLE *PINTNETIFHANDLE; */ typedef struct INTNETHDR { + /** The size of the frame. */ + uint32_t cbFrame : 24; /** Header type. This is currently serving as a magic, it * can be extended later to encode special command frames and stuff. */ - uint16_t u16Type; - /** The size of the frame. */ - uint16_t cbFrame; + uint32_t u8Type : 8; /** The offset from the start of this header to where the actual frame starts. * This is used to keep the frame it self contiguous in virtual memory and * thereby both simplify access as well as the descriptor. */ @@ -235,16 +235,16 @@ typedef INTNETHDR const *PCINTNETHDR; AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT); AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT); -/** @name Frame types (INTNETHDR::u16Type). +/** @name Frame types (INTNETHDR::u8Type). * @{ */ /** Normal frames. */ -#define INTNETHDR_TYPE_FRAME 0x2442 +#define INTNETHDR_TYPE_FRAME 0x42 /** Padding frames. */ -#define INTNETHDR_TYPE_PADDING 0x3553 +#define INTNETHDR_TYPE_PADDING 0x53 /** Generic segment offload frames. * The frame starts with a PDMNETWORKGSO structure which is followed by the * header template and data. */ -#define INTNETHDR_TYPE_GSO 0x4664 +#define INTNETHDR_TYPE_GSO 0x64 AssertCompileSize(PDMNETWORKGSO, 8); /** @} */ @@ -257,9 +257,9 @@ AssertCompileSize(PDMNETWORKGSO, 8); { \ AssertPtr(pHdr); \ Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \ - Assert( (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \ - || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \ - || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \ + Assert( (pHdr)->u8Type == INTNETHDR_TYPE_FRAME \ + || (pHdr)->u8Type == INTNETHDR_TYPE_GSO \ + || (pHdr)->u8Type == INTNETHDR_TYPE_PADDING); \ { \ uintptr_t const offHdr = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \ uintptr_t const offFrame = offHdr + (pHdr)->offFrame; \ diff --git a/include/VBox/intnetinline.h b/include/VBox/intnetinline.h index bcc42f1a..77d8dbb2 100644 --- a/include/VBox/intnetinline.h +++ b/include/VBox/intnetinline.h @@ -8,7 +8,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; @@ -43,13 +43,13 @@ * Valid internal networking frame type. * * @returns true / false. - * @param u16Type The frame type to check. + * @param u8Type The frame type to check. */ -DECLINLINE(bool) IntNetIsValidFrameType(uint16_t u16Type) +DECLINLINE(bool) IntNetIsValidFrameType(uint8_t u8Type) { - if (RT_LIKELY( u16Type == INTNETHDR_TYPE_FRAME - || u16Type == INTNETHDR_TYPE_GSO - || u16Type == INTNETHDR_TYPE_PADDING)) + if (RT_LIKELY( u8Type == INTNETHDR_TYPE_FRAME + || u8Type == INTNETHDR_TYPE_GSO + || u8Type == INTNETHDR_TYPE_PADDING)) return true; return false; } @@ -327,7 +327,7 @@ DECLINLINE(void *) IntNetHdrGetFramePtr(PCINTNETHDR pHdr, PCINTNETBUF pBuf) uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame; #ifdef VBOX_STRICT const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf; - Assert(IntNetIsValidFrameType(pHdr->u16Type)); + Assert(IntNetIsValidFrameType(pHdr->u8Type)); Assert(off < pBuf->cbBuf); Assert(off + pHdr->cbFrame <= pBuf->cbBuf); #endif @@ -353,7 +353,7 @@ DECLINLINE(PPDMNETWORKGSO) IntNetHdrGetGsoContext(PCINTNETHDR pHdr, PCINTNETBUF PPDMNETWORKGSO pGso = (PPDMNETWORKGSO)((uint8_t *)pHdr + pHdr->offFrame); #ifdef VBOX_STRICT const uintptr_t off = (uintptr_t)pGso - (uintptr_t)pBuf; - Assert(pHdr->u16Type == INTNETHDR_TYPE_GSO); + Assert(pHdr->u8Type == INTNETHDR_TYPE_GSO); Assert(off < pBuf->cbBuf); Assert(off + pHdr->cbFrame <= pBuf->cbBuf); #endif @@ -374,7 +374,7 @@ DECLINLINE(void) IntNetRingSkipFrame(PINTNETRINGBUF pRingBuf) Assert(offReadOld >= pRingBuf->offStart); Assert(offReadOld < pRingBuf->offEnd); Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); - Assert(IntNetIsValidFrameType(pHdr->u16Type)); + Assert(IntNetIsValidFrameType(pHdr->u8Type)); /* skip the frame */ uint32_t offReadNew = offReadOld + pHdr->offFrame + pHdr->cbFrame; @@ -401,7 +401,7 @@ DECLINLINE(void) IntNetRingSkipFrame(PINTNETRINGBUF pRingBuf) * Don't touch this! * @param ppvFrame Where to return the frame pointer. */ -DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint16_t u16Type, +DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint8_t u8Type, PINTNETHDR *ppHdr, void **ppvFrame) { /* @@ -425,11 +425,11 @@ DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_ offNew = pRingBuf->offStart; if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt))) return VERR_WRONG_ORDER; /* race */ - Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame)); + Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = u16Type; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = u8Type; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); *ppHdr = pHdr; @@ -446,11 +446,11 @@ DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_ uint32_t offNew = pRingBuf->offStart + cb; if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt))) return VERR_WRONG_ORDER; /* race */ - Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame)); + Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = u16Type; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = u8Type; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = pRingBuf->offStart - offWriteInt; *ppHdr = pHdr; @@ -466,11 +466,11 @@ DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_ uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR); if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt))) return VERR_WRONG_ORDER; /* race */ - Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame)); + Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = u16Type; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = u8Type; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); *ppHdr = pHdr; @@ -560,7 +560,7 @@ DECLINLINE(void) IntNetRingCommitFrame(PINTNETRINGBUF pRingBuf, PINTNETHDR pHdr) Assert(offWriteCom == pRingBuf->offEnd); offWriteCom = pRingBuf->offStart; } - Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, cbFrame)); + Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, cbFrame)); ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom); STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame); STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames); @@ -588,7 +588,7 @@ DECLINLINE(void) IntNetRingCommitFrameEx(PINTNETRINGBUF pRingBuf, PINTNETHDR pHd INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf); Assert(pRingBuf->offWriteCom == ((uintptr_t)pHdr - (uintptr_t)pRingBuf)); - if (pHdr->u16Type == INTNETHDR_TYPE_GSO) + if (pHdr->u8Type == INTNETHDR_TYPE_GSO) cbUsed += sizeof(PDMNETWORKGSO); /* @@ -612,13 +612,14 @@ DECLINLINE(void) IntNetRingCommitFrameEx(PINTNETRINGBUF pRingBuf, PINTNETHDR pHd { /** @todo Later: Try unallocate the extra memory. */ PINTNETHDR pHdrPadding = (PINTNETHDR)((uint8_t *)pHdr + pHdr->offFrame + cbAlignedUsed); - pHdrPadding->u16Type = INTNETHDR_TYPE_PADDING; - pHdrPadding->cbFrame = (uint16_t)(cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR)); + pHdrPadding->u8Type = INTNETHDR_TYPE_PADDING; + pHdrPadding->cbFrame = cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR); + Assert(pHdrPadding->cbFrame == cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR)); pHdrPadding->offFrame = sizeof(INTNETHDR); - pHdr->cbFrame = (uint16_t)cbUsed; + pHdr->cbFrame = cbUsed; Assert(pHdr->cbFrame == cbUsed); } - Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed)); + Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed)); ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom); STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbUsed); STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames); @@ -664,8 +665,8 @@ DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFram Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (1)\n", offWriteInt, offNew)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = INTNETHDR_TYPE_FRAME; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = INTNETHDR_TYPE_FRAME; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); memcpy(pHdr + 1, pvFrame, cbFrame); @@ -689,8 +690,8 @@ DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFram Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (2)\n", offWriteInt, offNew)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = INTNETHDR_TYPE_FRAME; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = INTNETHDR_TYPE_FRAME; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = pRingBuf->offStart - offWriteInt; memcpy((uint8_t *)pRingBuf + pRingBuf->offStart, pvFrame, cbFrame); @@ -713,8 +714,8 @@ DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFram Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (3)\n", offWriteInt, offNew)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = INTNETHDR_TYPE_FRAME; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = INTNETHDR_TYPE_FRAME; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); memcpy(pHdr + 1, pvFrame, cbFrame); diff --git a/include/VBox/log.h b/include/VBox/log.h index 05d53b7b..276caa5d 100644 --- a/include/VBox/log.h +++ b/include/VBox/log.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -147,6 +147,8 @@ typedef enum LOGGROUP LOG_GROUP_DEV_VMM_BACKDOOR, /** VMM Device group for logging guest backdoor logging to stderr. */ LOG_GROUP_DEV_VMM_STDERR, + /** VMSVGA Device group. */ + LOG_GROUP_DEV_VMSVGA, /** Disassembler group. */ LOG_GROUP_DIS, /** Generic driver group. */ @@ -229,16 +231,362 @@ typedef enum LOGGROUP LOG_GROUP_HGCM, /** HGSMI group */ LOG_GROUP_HGSMI, - /** HWACCM group. */ - LOG_GROUP_HWACCM, + /** HM group. */ + LOG_GROUP_HM, /** IEM group. */ LOG_GROUP_IEM, /** IOM group. */ LOG_GROUP_IOM, /** XPCOM IPC group. */ LOG_GROUP_IPC, + /** lwIP group. */ + LOG_GROUP_LWIP, + /** lwIP group, api_lib.c API_LIB_DEBUG */ + LOG_GROUP_LWIP_API_LIB, + /** lwIP group, api_msg.c API_MSG_DEBUG */ + LOG_GROUP_LWIP_API_MSG, + /** lwIP group, etharp.c ETHARP_DEBUG */ + LOG_GROUP_LWIP_ETHARP, + /** lwIP group, icmp.c ICMP_DEBUG */ + LOG_GROUP_LWIP_ICMP, + /** lwIP group, igmp.c IGMP_DEBUG */ + LOG_GROUP_LWIP_IGMP, + /** lwIP group, inet.c INET_DEBUG */ + LOG_GROUP_LWIP_INET, + /** lwIP group, IP_DEBUG (sic!) */ + LOG_GROUP_LWIP_IP4, + /** lwIP group, ip_frag.c IP_REASS_DEBUG (sic!) */ + LOG_GROUP_LWIP_IP4_REASS, + /** lwIP group, IP6_DEBUG */ + LOG_GROUP_LWIP_IP6, + /** lwIP group, mem.c MEM_DEBUG */ + LOG_GROUP_LWIP_MEM, + /** lwIP group, memp.c MEMP_DEBUG */ + LOG_GROUP_LWIP_MEMP, + /** lwIP group, netif.c NETIF_DEBUG */ + LOG_GROUP_LWIP_NETIF, + /** lwIP group, pbuf.c PBUF_DEBUG */ + LOG_GROUP_LWIP_PBUF, + /** lwIP group, raw.c RAW_DEBUG */ + LOG_GROUP_LWIP_RAW, + /** lwIP group, sockets.c SOCKETS_DEBUG */ + LOG_GROUP_LWIP_SOCKETS, + /** lwIP group, SYS_DEBUG */ + LOG_GROUP_LWIP_SYS, + /** lwIP group, TCP_DEBUG */ + LOG_GROUP_LWIP_TCP, + /** lwIP group, tcpip.c TCPIP_DEBUG */ + LOG_GROUP_LWIP_TCPIP, + /** lwIP group, TCP_CWND_DEBUG (congestion window) */ + LOG_GROUP_LWIP_TCP_CWND, + /** lwIP group, tcp_in.c TCP_FR_DEBUG (fast retransmit) */ + LOG_GROUP_LWIP_TCP_FR, + /** lwIP group, tcp_in.c TCP_INPUT_DEBUG */ + LOG_GROUP_LWIP_TCP_INPUT, + /** lwIP group, tcp_out.c TCP_OUTPUT_DEBUG */ + LOG_GROUP_LWIP_TCP_OUTPUT, + /** lwIP group, TCP_QLEN_DEBUG */ + LOG_GROUP_LWIP_TCP_QLEN, + /** lwIP group, TCP_RST_DEBUG */ + LOG_GROUP_LWIP_TCP_RST, + /** lwIP group, TCP_RTO_DEBUG (retransmit) */ + LOG_GROUP_LWIP_TCP_RTO, + /** lwIP group, tcp_in.c TCP_WND_DEBUG (window updates) */ + LOG_GROUP_LWIP_TCP_WND, + /** lwIP group, timers.c TIMERS_DEBUG */ + LOG_GROUP_LWIP_TIMERS, + /** lwIP group, udp.c UDP_DEBUG */ + LOG_GROUP_LWIP_UDP, /** Main group. */ LOG_GROUP_MAIN, + /** Main group, IAdditionsFacility. */ + LOG_GROUP_MAIN_ADDITIONSFACILITY, + /** Main group, IAdditionsStateChangedEvent. */ + LOG_GROUP_MAIN_ADDITIONSSTATECHANGEDEVENT, + /** Main group, IAppliance. */ + LOG_GROUP_MAIN_APPLIANCE, + /** Main group, IAudioAdapter. */ + LOG_GROUP_MAIN_AUDIOADAPTER, + /** Main group, IBandwidthControl. */ + LOG_GROUP_MAIN_BANDWIDTHCONTROL, + /** Main group, IBandwidthGroup. */ + LOG_GROUP_MAIN_BANDWIDTHGROUP, + /** Main group, IBandwidthGroupChangedEvent. */ + LOG_GROUP_MAIN_BANDWIDTHGROUPCHANGEDEVENT, + /** Main group, IBIOSSettings. */ + LOG_GROUP_MAIN_BIOSSETTINGS, + /** Main group, ICanShowWindowEvent. */ + LOG_GROUP_MAIN_CANSHOWWINDOWEVENT, + /** Main group, IClipboardModeChangedEvent. */ + LOG_GROUP_MAIN_CLIPBOARDMODECHANGEDEVENT, + /** Main group, IConsole. */ + LOG_GROUP_MAIN_CONSOLE, + /** Main group, ICPUChangedEvent. */ + LOG_GROUP_MAIN_CPUCHANGEDEVENT, + /** Main group, ICPUExecutionCapChangedEvent. */ + LOG_GROUP_MAIN_CPUEXECUTIONCAPCHANGEDEVENT, + /** Main group, IDHCPServer. */ + LOG_GROUP_MAIN_DHCPSERVER, + /** Main group, IDirectory. */ + LOG_GROUP_MAIN_DIRECTORY, + /** Main group, IDisplay. */ + LOG_GROUP_MAIN_DISPLAY, + /** Main group, IDragAndDropModeChangedEvent. */ + LOG_GROUP_MAIN_DRAGANDDROPMODECHANGEDEVENT, + /** Main group, IEmulatedUSB. */ + LOG_GROUP_MAIN_EMULATEDUSB, + /** Main group, IEvent. */ + LOG_GROUP_MAIN_EVENT, + /** Main group, IEventListener. */ + LOG_GROUP_MAIN_EVENTLISTENER, + /** Main group, IEventSource. */ + LOG_GROUP_MAIN_EVENTSOURCE, + /** Main group, IEventSourceChangedEvent. */ + LOG_GROUP_MAIN_EVENTSOURCECHANGEDEVENT, + /** Main group, IExtPack. */ + LOG_GROUP_MAIN_EXTPACK, + /** Main group, IExtPackBase. */ + LOG_GROUP_MAIN_EXTPACKBASE, + /** Main group, IExtPackFile. */ + LOG_GROUP_MAIN_EXTPACKFILE, + /** Main group, IExtPackManager. */ + LOG_GROUP_MAIN_EXTPACKMANAGER, + /** Main group, IExtPackPlugIn. */ + LOG_GROUP_MAIN_EXTPACKPLUGIN, + /** Main group, IExtraDataCanChangeEvent. */ + LOG_GROUP_MAIN_EXTRADATACANCHANGEEVENT, + /** Main group, IExtraDataChangedEvent. */ + LOG_GROUP_MAIN_EXTRADATACHANGEDEVENT, + /** Main group, IFile. */ + LOG_GROUP_MAIN_FILE, + /** Main group, IFramebuffer. */ + LOG_GROUP_MAIN_FRAMEBUFFER, + /** Main group, IFramebufferOverlay. */ + LOG_GROUP_MAIN_FRAMEBUFFEROVERLAY, + /** Main group, IFsObjInfo. */ + LOG_GROUP_MAIN_FSOBJINFO, + /** Main group, IGuest. */ + LOG_GROUP_MAIN_GUEST, + /** Main group, IGuestDirectory. */ + LOG_GROUP_MAIN_GUESTDIRECTORY, + /** Main group, IGuestErrorInfo. */ + LOG_GROUP_MAIN_GUESTERRORINFO, + /** Main group, IGuestFile. */ + LOG_GROUP_MAIN_GUESTFILE, + /** Main group, IGuestFileEvent. */ + LOG_GROUP_MAIN_GUESTFILEEVENT, + /** Main group, IGuestFileIOEvent. */ + LOG_GROUP_MAIN_GUESTFILEIOEVENT, + /** Main group, IGuestFileOffsetChangedEvent. */ + LOG_GROUP_MAIN_GUESTFILEOFFSETCHANGEDEVENT, + /** Main group, IGuestFileReadEvent. */ + LOG_GROUP_MAIN_GUESTFILEREADEVENT, + /** Main group, IGuestFileRegisteredEvent. */ + LOG_GROUP_MAIN_GUESTFILEREGISTEREDEVENT, + /** Main group, IGuestFileStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTFILESTATECHANGEDEVENT, + /** Main group, IGuestFileWriteEvent. */ + LOG_GROUP_MAIN_GUESTFILEWRITEEVENT, + /** Main group, IGuestFsObjInfo. */ + LOG_GROUP_MAIN_GUESTFSOBJINFO, + /** Main group, IGuestKeyboardEvent. */ + LOG_GROUP_MAIN_GUESTKEYBOARDEVENT, + /** Main group, IGuestMonitorChangedEvent. */ + LOG_GROUP_MAIN_GUESTMONITORCHANGEDEVENT, + /** Main group, IGuestMouseEvent. */ + LOG_GROUP_MAIN_GUESTMOUSEEVENT, + /** Main group, IGuestMultiTouchEvent. */ + LOG_GROUP_MAIN_GUESTMULTITOUCHEVENT, + /** Main group, IGuestOSType. */ + LOG_GROUP_MAIN_GUESTOSTYPE, + /** Main group, IGuestProcess. */ + LOG_GROUP_MAIN_GUESTPROCESS, + /** Main group, IGuestProcessEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSEVENT, + /** Main group, IGuestProcessInputNotifyEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSINPUTNOTIFYEVENT, + /** Main group, IGuestProcessIOEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSIOEVENT, + /** Main group, IGuestProcessOutputEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSOUTPUTEVENT, + /** Main group, IGuestProcessRegisteredEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSREGISTEREDEVENT, + /** Main group, IGuestProcessStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSSTATECHANGEDEVENT, + /** Main group, IGuestPropertyChangedEvent. */ + LOG_GROUP_MAIN_GUESTPROPERTYCHANGEDEVENT, + /** Main group, IGuestSession. */ + LOG_GROUP_MAIN_GUESTSESSION, + /** Main group, IGuestSessionEvent. */ + LOG_GROUP_MAIN_GUESTSESSIONEVENT, + /** Main group, IGuestSessionRegisteredEvent. */ + LOG_GROUP_MAIN_GUESTSESSIONREGISTEREDEVENT, + /** Main group, IGuestSessionStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTSESSIONSTATECHANGEDEVENT, + /** Main group, IGuestUserStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTUSERSTATECHANGEDEVENT, + /** Main group, IHost. */ + LOG_GROUP_MAIN_HOST, + /** Main group, IHostNameResolutionConfigurationChangeEvent. */ + LOG_GROUP_MAIN_HOSTNAMERESOLUTIONCONFIGURATIONCHANGEEVENT, + /** Main group, IHostNetworkInterface. */ + LOG_GROUP_MAIN_HOSTNETWORKINTERFACE, + /** Main group, IHostPCIDevicePlugEvent. */ + LOG_GROUP_MAIN_HOSTPCIDEVICEPLUGEVENT, + /** Main group, IHostUSBDevice. */ + LOG_GROUP_MAIN_HOSTUSBDEVICE, + /** Main group, IHostUSBDeviceFilter. */ + LOG_GROUP_MAIN_HOSTUSBDEVICEFILTER, + /** Main group, IHostVideoInputDevice. */ + LOG_GROUP_MAIN_HOSTVIDEOINPUTDEVICE, + /** Main group, IInternalMachineControl. */ + LOG_GROUP_MAIN_INTERNALMACHINECONTROL, + /** Main group, IInternalSessionControl. */ + LOG_GROUP_MAIN_INTERNALSESSIONCONTROL, + /** Main group, IKeyboard. */ + LOG_GROUP_MAIN_KEYBOARD, + /** Main group, IKeyboardLedsChangedEvent. */ + LOG_GROUP_MAIN_KEYBOARDLEDSCHANGEDEVENT, + /** Main group, IMachine. */ + LOG_GROUP_MAIN_MACHINE, + /** Main group, IMachineDataChangedEvent. */ + LOG_GROUP_MAIN_MACHINEDATACHANGEDEVENT, + /** Main group, IMachineDebugger. */ + LOG_GROUP_MAIN_MACHINEDEBUGGER, + /** Main group, IMachineEvent. */ + LOG_GROUP_MAIN_MACHINEEVENT, + /** Main group, IMachineRegisteredEvent. */ + LOG_GROUP_MAIN_MACHINEREGISTEREDEVENT, + /** Main group, IMachineStateChangedEvent. */ + LOG_GROUP_MAIN_MACHINESTATECHANGEDEVENT, + /** Main group, IMedium. */ + LOG_GROUP_MAIN_MEDIUM, + /** Main group, IMediumAttachment. */ + LOG_GROUP_MAIN_MEDIUMATTACHMENT, + /** Main group, IMediumChangedEvent. */ + LOG_GROUP_MAIN_MEDIUMCHANGEDEVENT, + /** Main group, IMediumFormat. */ + LOG_GROUP_MAIN_MEDIUMFORMAT, + /** Main group, IMediumRegisteredEvent. */ + LOG_GROUP_MAIN_MEDIUMREGISTEREDEVENT, + /** Main group, IMouse. */ + LOG_GROUP_MAIN_MOUSE, + /** Main group, IMouseCapabilityChangedEvent. */ + LOG_GROUP_MAIN_MOUSECAPABILITYCHANGEDEVENT, + /** Main group, IMousePointerShapeChangedEvent. */ + LOG_GROUP_MAIN_MOUSEPOINTERSHAPECHANGEDEVENT, + /** Main group, INATEngine. */ + LOG_GROUP_MAIN_NATENGINE, + /** Main group, INATNetwork. */ + LOG_GROUP_MAIN_NATNETWORK, + /** Main group, INATNetworkAlterEvent. */ + LOG_GROUP_MAIN_NATNETWORKALTEREVENT, + /** Main group, INATNetworkChangedEvent. */ + LOG_GROUP_MAIN_NATNETWORKCHANGEDEVENT, + /** Main group, INATNetworkCreationDeletionEvent. */ + LOG_GROUP_MAIN_NATNETWORKCREATIONDELETIONEVENT, + /** Main group, INATNetworkPortForwardEvent. */ + LOG_GROUP_MAIN_NATNETWORKPORTFORWARDEVENT, + /** Main group, INATNetworkSettingEvent. */ + LOG_GROUP_MAIN_NATNETWORKSETTINGEVENT, + /** Main group, INATNetworkStartStopEvent. */ + LOG_GROUP_MAIN_NATNETWORKSTARTSTOPEVENT, + /** Main group, INATRedirectEvent. */ + LOG_GROUP_MAIN_NATREDIRECTEVENT, + /** Main group, INetworkAdapter. */ + LOG_GROUP_MAIN_NETWORKADAPTER, + /** Main group, INetworkAdapterChangedEvent. */ + LOG_GROUP_MAIN_NETWORKADAPTERCHANGEDEVENT, + /** Main group, IParallelPort. */ + LOG_GROUP_MAIN_PARALLELPORT, + /** Main group, IParallelPortChangedEvent. */ + LOG_GROUP_MAIN_PARALLELPORTCHANGEDEVENT, + /** Main group, IPCIAddress. */ + LOG_GROUP_MAIN_PCIADDRESS, + /** Main group, IPCIDeviceAttachment. */ + LOG_GROUP_MAIN_PCIDEVICEATTACHMENT, + /** Main group, IPerformanceCollector. */ + LOG_GROUP_MAIN_PERFORMANCECOLLECTOR, + /** Main group, IPerformanceMetric. */ + LOG_GROUP_MAIN_PERFORMANCEMETRIC, + /** Main group, IProcess. */ + LOG_GROUP_MAIN_PROCESS, + /** Main group, IProgress. */ + LOG_GROUP_MAIN_PROGRESS, + /** Main group, IReusableEvent. */ + LOG_GROUP_MAIN_REUSABLEEVENT, + /** Main group, IRuntimeErrorEvent. */ + LOG_GROUP_MAIN_RUNTIMEERROREVENT, + /** Main group, ISerialPort. */ + LOG_GROUP_MAIN_SERIALPORT, + /** Main group, ISerialPortChangedEvent. */ + LOG_GROUP_MAIN_SERIALPORTCHANGEDEVENT, + /** Main group, ISession. */ + LOG_GROUP_MAIN_SESSION, + /** Main group, ISessionStateChangedEvent. */ + LOG_GROUP_MAIN_SESSIONSTATECHANGEDEVENT, + /** Main group, ISharedFolder. */ + LOG_GROUP_MAIN_SHAREDFOLDER, + /** Main group, ISharedFolderChangedEvent. */ + LOG_GROUP_MAIN_SHAREDFOLDERCHANGEDEVENT, + /** Main group, IShowWindowEvent. */ + LOG_GROUP_MAIN_SHOWWINDOWEVENT, + /** Main group, ISnapshot. */ + LOG_GROUP_MAIN_SNAPSHOT, + /** Main group, ISnapshotChangedEvent. */ + LOG_GROUP_MAIN_SNAPSHOTCHANGEDEVENT, + /** Main group, ISnapshotDeletedEvent. */ + LOG_GROUP_MAIN_SNAPSHOTDELETEDEVENT, + /** Main group, ISnapshotEvent. */ + LOG_GROUP_MAIN_SNAPSHOTEVENT, + /** Main group, ISnapshotTakenEvent. */ + LOG_GROUP_MAIN_SNAPSHOTTAKENEVENT, + /** Main group, IStateChangedEvent. */ + LOG_GROUP_MAIN_STATECHANGEDEVENT, + /** Main group, IStorageController. */ + LOG_GROUP_MAIN_STORAGECONTROLLER, + /** Main group, IStorageControllerChangedEvent. */ + LOG_GROUP_MAIN_STORAGECONTROLLERCHANGEDEVENT, + /** Main group, IStorageDeviceChangedEvent. */ + LOG_GROUP_MAIN_STORAGEDEVICECHANGEDEVENT, + /** Main group, ISystemProperties. */ + LOG_GROUP_MAIN_SYSTEMPROPERTIES, + /** Main group, IToken. */ + LOG_GROUP_MAIN_TOKEN, + /** Main group, IUSBController. */ + LOG_GROUP_MAIN_USBCONTROLLER, + /** Main group, IUSBControllerChangedEvent. */ + LOG_GROUP_MAIN_USBCONTROLLERCHANGEDEVENT, + /** Main group, IUSBDevice. */ + LOG_GROUP_MAIN_USBDEVICE, + /** Main group, IUSBDeviceFilter. */ + LOG_GROUP_MAIN_USBDEVICEFILTER, + /** Main group, IUSBDeviceFilters. */ + LOG_GROUP_MAIN_USBDEVICEFILTERS, + /** Main group, IUSBDeviceStateChangedEvent. */ + LOG_GROUP_MAIN_USBDEVICESTATECHANGEDEVENT, + /** Main group, IVBoxSVCAvailabilityChangedEvent. */ + LOG_GROUP_MAIN_VBOXSVCAVAILABILITYCHANGEDEVENT, + /** Main group, IVetoEvent. */ + LOG_GROUP_MAIN_VETOEVENT, + /** Main group, IVFSExplorer. */ + LOG_GROUP_MAIN_VFSEXPLORER, + /** Main group, IVideoCaptureChangedEvent. */ + LOG_GROUP_MAIN_VIDEOCAPTURECHANGEDEVENT, + /** Main group, IVirtualBox. */ + LOG_GROUP_MAIN_VIRTUALBOX, + /** Main group, IVirtualBoxClient. */ + LOG_GROUP_MAIN_VIRTUALBOXCLIENT, + /** Main group, IVirtualSystemDescription. */ + LOG_GROUP_MAIN_VIRTUALSYSTEMDESCRIPTION, + /** Main group, IVRDEServer. */ + LOG_GROUP_MAIN_VRDESERVER, + /** Main group, IVRDEServerChangedEvent. */ + LOG_GROUP_MAIN_VRDESERVERCHANGEDEVENT, + /** Main group, IVRDEServerInfo. */ + LOG_GROUP_MAIN_VRDESERVERINFO, + /** Main group, IVRDEServerInfoChangedEvent. */ + LOG_GROUP_MAIN_VRDESERVERINFOCHANGEDEVENT, /** Misc. group intended for external use only. */ LOG_GROUP_MISC, /** MM group. */ @@ -337,10 +685,16 @@ typedef enum LOGGROUP LOG_GROUP_USB_FILTER, /** USB keyboard device group. */ LOG_GROUP_USB_KBD, + /** USB mouse/tablet device group. */ + LOG_GROUP_USB_MOUSE, /** MSD USB device group. */ LOG_GROUP_USB_MSD, /** USB webcam. */ LOG_GROUP_USB_WEBCAM, + /** VBox Guest Additions Driver (VBoxGuest). */ + LOG_GROUP_VBGD, + /** VBox Guest Additions Library. */ + LOG_GROUP_VBGL, /** Generic virtual disk layer. */ LOG_GROUP_VD, /** DMG virtual disk backend. */ @@ -437,7 +791,8 @@ typedef enum LOGGROUP "DEV_VIRTIO_NET", \ "DEV_VMM", \ "DEV_VMM_BACKDOOR", \ - "DEV_VMM_STDERR",\ + "DEV_VMM_STDERR", \ + "DEV_VMSVGA", \ "DIS", \ "DRV", \ "DRV_ACPI", \ @@ -456,12 +811,12 @@ typedef enum LOGGROUP "DRV_KBD_QUEUE", \ "DRV_LWIP", \ "DRV_MINIPORT", \ - "DRV_MOUSE", \ + "DRV_MOUSE", \ "DRV_MOUSE_QUEUE", \ "DRV_NAMEDPIPE", \ "DRV_NAT", \ "DRV_RAW_IMAGE", \ - "DRV_SCSI", \ + "DRV_SCSI", \ "DRV_SCSIHOST", \ "DRV_TRANSPORT_ASYNC", \ "DRV_TUN", \ @@ -479,11 +834,184 @@ typedef enum LOGGROUP "GVMM", \ "HGCM", \ "HGSMI", \ - "HWACCM", \ + "HM", \ "IEM", \ "IOM", \ "IPC", \ + "LWIP", \ + "LWIP_API_LIB", \ + "LWIP_API_MSG", \ + "LWIP_ETHARP", \ + "LWIP_ICMP", \ + "LWIP_IGMP", \ + "LWIP_INET", \ + "LWIP_IP4", \ + "LWIP_IP4_REASS", \ + "LWIP_IP6", \ + "LWIP_MEM", \ + "LWIP_MEMP", \ + "LWIP_NETIF", \ + "LWIP_PBUF", \ + "LWIP_RAW", \ + "LWIP_SOCKETS", \ + "LWIP_SYS", \ + "LWIP_TCP", \ + "LWIP_TCPIP", \ + "LWIP_TCP_CWND", \ + "LWIP_TCP_FR", \ + "LWIP_TCP_INPUT", \ + "LWIP_TCP_OUTPUT", \ + "LWIP_TCP_QLEN", \ + "LWIP_TCP_RST", \ + "LWIP_TCP_RTO", \ + "LWIP_TCP_WND", \ + "LWIP_TIMERS", \ + "LWIP_UDP", \ "MAIN", \ + "MAIN_ADDITIONSFACILITY", \ + "MAIN_ADDITIONSSTATECHANGEDEVENT", \ + "MAIN_APPLIANCE", \ + "MAIN_AUDIOADAPTER", \ + "MAIN_BANDWIDTHCONTROL", \ + "MAIN_BANDWIDTHGROUP", \ + "MAIN_BANDWIDTHGROUPCHANGEDEVENT", \ + "MAIN_BIOSSETTINGS", \ + "MAIN_CANSHOWWINDOWEVENT", \ + "MAIN_CLIPBOARDMODECHANGEDEVENT", \ + "MAIN_CONSOLE", \ + "MAIN_CPUCHANGEDEVENT", \ + "MAIN_CPUEXECUTIONCAPCHANGEDEVENT", \ + "MAIN_DHCPSERVER", \ + "MAIN_DIRECTORY", \ + "MAIN_DISPLAY", \ + "MAIN_DRAGANDDROPMODECHANGEDEVENT", \ + "MAIN_EMULATEDUSB", \ + "MAIN_EVENT", \ + "MAIN_EVENTLISTENER", \ + "MAIN_EVENTSOURCE", \ + "MAIN_EVENTSOURCECHANGEDEVENT", \ + "MAIN_EXTPACK", \ + "MAIN_EXTPACKBASE", \ + "MAIN_EXTPACKFILE", \ + "MAIN_EXTPACKMANAGER", \ + "MAIN_EXTPACKPLUGIN", \ + "MAIN_EXTRADATACANCHANGEEVENT", \ + "MAIN_EXTRADATACHANGEDEVENT", \ + "MAIN_FILE", \ + "MAIN_FRAMEBUFFER", \ + "MAIN_FRAMEBUFFEROVERLAY", \ + "MAIN_FSOBJINFO", \ + "MAIN_GUEST", \ + "MAIN_GUESTDIRECTORY", \ + "MAIN_GUESTERRORINFO", \ + "MAIN_GUESTFILE", \ + "MAIN_GUESTFILEEVENT", \ + "MAIN_GUESTFILEIOEVENT", \ + "MAIN_GUESTFILEOFFSETCHANGEDEVENT", \ + "MAIN_GUESTFILEREADEVENT", \ + "MAIN_GUESTFILEREGISTEREDEVENT", \ + "MAIN_GUESTFILESTATECHANGEDEVENT", \ + "MAIN_GUESTFILEWRITEEVENT", \ + "MAIN_GUESTFSOBJINFO", \ + "MAIN_GUESTKEYBOARDEVENT", \ + "MAIN_GUESTMONITORCHANGEDEVENT", \ + "MAIN_GUESTMOUSEEVENT", \ + "MAIN_GUESTMULTITOUCHEVENT", \ + "MAIN_GUESTOSTYPE", \ + "MAIN_GUESTPROCESS", \ + "MAIN_GUESTPROCESSEVENT", \ + "MAIN_GUESTPROCESSINPUTNOTIFYEVENT", \ + "MAIN_GUESTPROCESSIOEVENT", \ + "MAIN_GUESTPROCESSOUTPUTEVENT", \ + "MAIN_GUESTPROCESSREGISTEREDEVENT", \ + "MAIN_GUESTPROCESSSTATECHANGEDEVENT", \ + "MAIN_GUESTPROPERTYCHANGEDEVENT", \ + "MAIN_GUESTSESSION", \ + "MAIN_GUESTSESSIONEVENT", \ + "MAIN_GUESTSESSIONREGISTEREDEVENT", \ + "MAIN_GUESTSESSIONSTATECHANGEDEVENT", \ + "MAIN_GUESTUSERSTATECHANGEDEVENT", \ + "MAIN_HOST", \ + "MAIN_HOSTNAMERESOLUTIONCONFIGURATIONCHANGEEVENT", \ + "MAIN_HOSTNETWORKINTERFACE", \ + "MAIN_HOSTPCIDEVICEPLUGEVENT", \ + "MAIN_HOSTUSBDEVICE", \ + "MAIN_HOSTUSBDEVICEFILTER", \ + "MAIN_HOSTVIDEOINPUTDEVICE", \ + "MAIN_INTERNALMACHINECONTROL", \ + "MAIN_INTERNALSESSIONCONTROL", \ + "MAIN_KEYBOARD", \ + "MAIN_KEYBOARDLEDSCHANGEDEVENT", \ + "MAIN_MACHINE", \ + "MAIN_MACHINEDATACHANGEDEVENT", \ + "MAIN_MACHINEDEBUGGER", \ + "MAIN_MACHINEEVENT", \ + "MAIN_MACHINEREGISTEREDEVENT", \ + "MAIN_MACHINESTATECHANGEDEVENT", \ + "MAIN_MEDIUM", \ + "MAIN_MEDIUMATTACHMENT", \ + "MAIN_MEDIUMCHANGEDEVENT", \ + "MAIN_MEDIUMFORMAT", \ + "MAIN_MEDIUMREGISTEREDEVENT", \ + "MAIN_MOUSE", \ + "MAIN_MOUSECAPABILITYCHANGEDEVENT", \ + "MAIN_MOUSEPOINTERSHAPECHANGEDEVENT", \ + "MAIN_NATENGINE", \ + "MAIN_NATNETWORK", \ + "MAIN_NATNETWORKALTEREVENT", \ + "MAIN_NATNETWORKCHANGEDEVENT", \ + "MAIN_NATNETWORKCREATIONDELETIONEVENT", \ + "MAIN_NATNETWORKPORTFORWARDEVENT", \ + "MAIN_NATNETWORKSETTINGEVENT", \ + "MAIN_NATNETWORKSTARTSTOPEVENT", \ + "MAIN_NATREDIRECTEVENT", \ + "MAIN_NETWORKADAPTER", \ + "MAIN_NETWORKADAPTERCHANGEDEVENT", \ + "MAIN_PARALLELPORT", \ + "MAIN_PARALLELPORTCHANGEDEVENT", \ + "MAIN_PCIADDRESS", \ + "MAIN_PCIDEVICEATTACHMENT", \ + "MAIN_PERFORMANCECOLLECTOR", \ + "MAIN_PERFORMANCEMETRIC", \ + "MAIN_PROCESS", \ + "MAIN_PROGRESS", \ + "MAIN_REUSABLEEVENT", \ + "MAIN_RUNTIMEERROREVENT", \ + "MAIN_SERIALPORT", \ + "MAIN_SERIALPORTCHANGEDEVENT", \ + "MAIN_SESSION", \ + "MAIN_SESSIONSTATECHANGEDEVENT", \ + "MAIN_SHAREDFOLDER", \ + "MAIN_SHAREDFOLDERCHANGEDEVENT", \ + "MAIN_SHOWWINDOWEVENT", \ + "MAIN_SNAPSHOT", \ + "MAIN_SNAPSHOTCHANGEDEVENT", \ + "MAIN_SNAPSHOTDELETEDEVENT", \ + "MAIN_SNAPSHOTEVENT", \ + "MAIN_SNAPSHOTTAKENEVENT", \ + "MAIN_STATECHANGEDEVENT", \ + "MAIN_STORAGECONTROLLER", \ + "MAIN_STORAGECONTROLLERCHANGEDEVENT", \ + "MAIN_STORAGEDEVICECHANGEDEVENT", \ + "MAIN_SYSTEMPROPERTIES", \ + "MAIN_TOKEN", \ + "MAIN_USBCONTROLLER", \ + "MAIN_USBCONTROLLERCHANGEDEVENT", \ + "MAIN_USBDEVICE", \ + "MAIN_USBDEVICEFILTER", \ + "MAIN_USBDEVICEFILTERS", \ + "MAIN_USBDEVICESTATECHANGEDEVENT", \ + "MAIN_VBOXSVCAVAILABILITYCHANGEDEVENT", \ + "MAIN_VETOEVENT", \ + "MAIN_VFSEXPLORER", \ + "MAIN_VIDEOCAPTURECHANGEDEVENT", \ + "MAIN_VIRTUALBOX", \ + "MAIN_VIRTUALBOXCLIENT", \ + "MAIN_VIRTUALSYSTEMDESCRIPTION", \ + "MAIN_VRDESERVER", \ + "MAIN_VRDESERVERCHANGEDEVENT", \ + "MAIN_VRDESERVERINFO", \ + "MAIN_VRDESERVERINFOCHANGEDEVENT", \ "MISC", \ "MM", \ "MM_HEAP", \ @@ -533,8 +1061,11 @@ typedef enum LOGGROUP "USB_DRV", \ "USB_FILTER", \ "USB_KBD", \ + "USB_MOUSE", \ "USB_MSD", \ "USB_WEBCAM", \ + "VBGD", \ + "VBGL", \ "VD", \ "VD_DMG", \ "VD_ISCSI", \ diff --git a/include/VBox/nasm.mac b/include/VBox/nasm.mac index 416a72f6..a8010a67 100644 --- a/include/VBox/nasm.mac +++ b/include/VBox/nasm.mac @@ -5,7 +5,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/include/VBox/ostypes.h b/include/VBox/ostypes.h index cbc0b739..890c2be4 100644 --- a/include/VBox/ostypes.h +++ b/include/VBox/ostypes.h @@ -3,7 +3,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; @@ -43,6 +43,7 @@ RT_C_DECLS_BEGIN typedef enum VBOXOSTYPE { VBOXOSTYPE_Unknown = 0, + VBOXOSTYPE_Unknown_x64 = 0x00100, VBOXOSTYPE_DOS = 0x10000, VBOXOSTYPE_Win31 = 0x15000, VBOXOSTYPE_Win9x = 0x20000, @@ -50,6 +51,7 @@ typedef enum VBOXOSTYPE VBOXOSTYPE_Win98 = 0x22000, VBOXOSTYPE_WinMe = 0x23000, VBOXOSTYPE_WinNT = 0x30000, + VBOXOSTYPE_WinNT_x64 = 0x30100, VBOXOSTYPE_WinNT4 = 0x31000, VBOXOSTYPE_Win2k = 0x32000, VBOXOSTYPE_WinXP = 0x33000, @@ -65,6 +67,8 @@ typedef enum VBOXOSTYPE VBOXOSTYPE_Win8 = 0x38000, VBOXOSTYPE_Win8_x64 = 0x38100, VBOXOSTYPE_Win2k12_x64 = 0x39100, + VBOXOSTYPE_Win81 = 0x3A000, + VBOXOSTYPE_Win81_x64 = 0x3A100, VBOXOSTYPE_OS2 = 0x40000, VBOXOSTYPE_OS2Warp3 = 0x41000, VBOXOSTYPE_OS2Warp4 = 0x42000, @@ -115,7 +119,14 @@ typedef enum VBOXOSTYPE VBOXOSTYPE_QNX = 0xA0000, VBOXOSTYPE_MacOS = 0xB0000, VBOXOSTYPE_MacOS_x64 = 0xB0100, + VBOXOSTYPE_MacOS106 = 0xB2000, + VBOXOSTYPE_MacOS106_x64 = 0xB2100, + VBOXOSTYPE_MacOS107_x64 = 0xB3100, + VBOXOSTYPE_MacOS108_x64 = 0xB4100, + VBOXOSTYPE_MacOS109_x64 = 0xB5100, VBOXOSTYPE_JRockitVE = 0xC0000, + VBOXOSTYPE_Haiku = 0xD0000, + VBOXOSTYPE_Haiku_x64 = 0xD0100, /** The bit number which indicates 64-bit or 32-bit. */ #define VBOXOSTYPE_x64_BIT 8 /** The mask which indicates 64-bit. */ diff --git a/include/VBox/param.h b/include/VBox/param.h index 0f94967c..86a5c118 100644 --- a/include/VBox/param.h +++ b/include/VBox/param.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2009 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/include/VBox/pci.h b/include/VBox/pci.h index 526c7298..4c6b5fd6 100644 --- a/include/VBox/pci.h +++ b/include/VBox/pci.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -87,6 +87,8 @@ typedef enum PCIADDRESSSPACE * * @param enmType One of the PCI_ADDRESS_SPACE_* values. * + * @remarks Called with the PDM lock held. The device lock is NOT take because + * that is very likely be a lock order violation. */ typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType); /** Pointer to a FNPCIIOREGIONMAP() function. */ @@ -470,6 +472,9 @@ typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP; * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance. * @param Address The configuration space register address. [0..4096] * @param cb The register size. [1,2,4] + * + * @remarks Called with the PDM lock held. The device lock is NOT take because + * that is very likely be a lock order violation. */ typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb); /** Pointer to a FNPCICONFIGREAD() function. */ @@ -485,6 +490,9 @@ typedef PFNPCICONFIGREAD *PPFNPCICONFIGREAD; * @param u32Value The value that's being written. The number of bits actually used from * this value is determined by the cb parameter. * @param cb The register size. [1,2,4] + * + * @remarks Called with the PDM lock held. The device lock is NOT take because + * that is very likely be a lock order violation. */ typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb); /** Pointer to a FNPCICONFIGWRITE() function. */ @@ -537,47 +545,48 @@ typedef struct PCIDevice /** @} */ } PCIDEVICE; -/* @todo: handle extended space access */ -DECLINLINE(void) PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t uOffset, uint8_t u8Value) +/** @todo handle extended space access. */ + +DECLINLINE(void) PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t offReg, uint8_t u8Value) { - pPciDev->config[uOffset] = u8Value; + pPciDev->config[offReg] = u8Value; } -DECLINLINE(uint8_t) PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint8_t) PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t offReg) { - return pPciDev->config[uOffset]; + return pPciDev->config[offReg]; } -DECLINLINE(void) PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint16_t u16Value) +DECLINLINE(void) PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t offReg, uint16_t u16Value) { - *(uint16_t*)&pPciDev->config[uOffset] = RT_H2LE_U16(u16Value); + *(uint16_t*)&pPciDev->config[offReg] = RT_H2LE_U16(u16Value); } -DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t offReg) { - uint16_t u16Value = *(uint16_t*)&pPciDev->config[uOffset]; + uint16_t u16Value = *(uint16_t*)&pPciDev->config[offReg]; return RT_H2LE_U16(u16Value); } -DECLINLINE(void) PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint32_t u32Value) +DECLINLINE(void) PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t offReg, uint32_t u32Value) { - *(uint32_t*)&pPciDev->config[uOffset] = RT_H2LE_U32(u32Value); + *(uint32_t*)&pPciDev->config[offReg] = RT_H2LE_U32(u32Value); } -DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t offReg) { - uint32_t u32Value = *(uint32_t*)&pPciDev->config[uOffset]; + uint32_t u32Value = *(uint32_t*)&pPciDev->config[offReg]; return RT_H2LE_U32(u32Value); } -DECLINLINE(void) PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint64_t u64Value) +DECLINLINE(void) PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t offReg, uint64_t u64Value) { - *(uint64_t*)&pPciDev->config[uOffset] = RT_H2LE_U64(u64Value); + *(uint64_t*)&pPciDev->config[offReg] = RT_H2LE_U64(u64Value); } -DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t offReg) { - uint64_t u64Value = *(uint64_t*)&pPciDev->config[uOffset]; + uint64_t u64Value = *(uint64_t*)&pPciDev->config[offReg]; return RT_H2LE_U64(u64Value); } diff --git a/include/VBox/scsi.h b/include/VBox/scsi.h index 20bcd5e1..c0ab641c 100644 --- a/include/VBox/scsi.h +++ b/include/VBox/scsi.h @@ -3,7 +3,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; @@ -90,6 +90,7 @@ typedef enum SCSICMD SCSI_SET_READ_AHEAD = 0xa7, SCSI_SET_STREAMING = 0xb6, SCSI_START_STOP_UNIT = 0x1b, + SCSI_LOAD_UNLOAD = 0x1b, SCSI_STOP_PLAY_SCAN = 0x4e, /** Synchronize Cache command. */ SCSI_SYNCHRONIZE_CACHE = 0x35, @@ -110,13 +111,19 @@ typedef enum SCSICMD SCSI_REPORT_DENSITY = 0x44, /** Rezero Unit command. Obsolete for ages now, but used by cdrecord. */ SCSI_REZERO_UNIT = 0x01, + SCSI_REWIND = 0x01, SCSI_SERVICE_ACTION_IN_16 = 0x9e, SCSI_READ_16 = 0x88, SCSI_WRITE_16 = 0x8a, SCSI_READ_6 = 0x08, SCSI_WRITE_6 = 0x0a, SCSI_LOG_SENSE = 0x4d, - SCSI_UNMAP = 0x42 + SCSI_UNMAP = 0x42, + SCSI_RESERVE_6 = 0x16, + SCSI_RELEASE_6 = 0x17, + SCSI_RESERVE_10 = 0x56, + SCSI_RELEASE_10 = 0x57, + SCSI_READ_BLOCK_LIMITS = 0x05 } SCSICMD; /** @@ -176,8 +183,12 @@ typedef enum SCSISVCACTIONIN #define SCSI_SENSE_VOLUME_OVERFLOW 13 #define SCSI_SENSE_MISCOMPARE 14 +/* Additional sense bit flags (to be ORed with sense key). */ +#define SCSI_SENSE_FLAG_FILEMARK 0x80 +#define SCSI_SENSE_FLAG_EOM 0x40 +#define SCSI_SENSE_FLAG_ILI 0x20 -/* additional sense keys */ +/* Additional sense keys */ #define SCSI_ASC_NONE 0x00 #define SCSI_ASC_WRITE_ERROR 0x0c #define SCSI_ASC_READ_ERROR 0x11 @@ -186,6 +197,7 @@ typedef enum SCSISVCACTIONIN #define SCSI_ASC_INV_FIELD_IN_CMD_PACKET 0x24 #define SCSI_ASC_WRITE_PROTECTED 0x27 #define SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 +#define SCSI_ASC_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED 0x29 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3a #define SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 #define SCSI_ASC_INVALID_MESSAGE 0x49 @@ -194,7 +206,14 @@ typedef enum SCSISVCACTIONIN #define SCSI_ASC_SYSTEM_RESOURCE_FAILURE 0x55 /** Additional sense code qualifiers (ASCQ). */ +/* NB: The ASC/ASCQ combination determines the full meaning. */ #define SCSI_ASCQ_SYSTEM_BUFFER_FULL 0x01 +#define SCSI_ASCQ_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED 0x00 +#define SCSI_ASCQ_END_OF_DATA_DETECTED 0x05 +#define SCSI_ASCQ_FILEMARK_DETECTED 0x01 +#define SCSI_ASCQ_EOP_EOM_DETECTED 0x02 +#define SCSI_ASCQ_SETMARK_DETECTED 0x03 +#define SCSI_ASCQ_BOP_BOM_DETECTED 0x04 /** @name SCSI_INQUIRY * @{ diff --git a/include/VBox/settings.h b/include/VBox/settings.h index 4c69a0e2..eb931d68 100644 --- a/include/VBox/settings.h +++ b/include/VBox/settings.h @@ -17,7 +17,7 @@ */ /* - * Copyright (C) 2007-2012 Oracle Corporation + * Copyright (C) 2007-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; @@ -50,6 +50,14 @@ #include #include +/** + * Maximum depth of the snapshot tree, to prevent stack overflows. + * XPCOM has a relatively low stack size for its workers, and we have + * to avoid crashes due to exceeding the limit both on reading and + * writing config files. + */ +#define SETTINGS_SNAPSHOT_DEPTH_MAX 250 + namespace xml { class ElementNode; @@ -153,6 +161,54 @@ struct MediaRegistry bool operator==(const MediaRegistry &m) const; }; +/** + * + */ +struct NATRule +{ + NATRule() + : proto(NATProtocol_TCP), + u16HostPort(0), + u16GuestPort(0) + {} + + bool operator==(const NATRule &r) const + { + return strName == r.strName + && proto == r.proto + && u16HostPort == r.u16HostPort + && strHostIP == r.strHostIP + && u16GuestPort == r.u16GuestPort + && strGuestIP == r.strGuestIP; + } + + com::Utf8Str strName; + NATProtocol_T proto; + uint16_t u16HostPort; + com::Utf8Str strHostIP; + uint16_t u16GuestPort; + com::Utf8Str strGuestIP; +}; +typedef std::list NATRuleList; + + +struct NATHostLoopbackOffset +{ + /** Note: 128/8 is only acceptable */ + com::Utf8Str strLoopbackHostAddress; + uint32_t u32Offset; + bool operator == (const com::Utf8Str& strAddr) + { + return (strLoopbackHostAddress == strAddr); + } + + bool operator == (uint32_t off) + { + return (this->u32Offset == off); + } +}; +typedef std::list NATLoopbackOffsetList; + /** * Common base class for both MainConfigFile and MachineConfigFile * which contains some common logic for both. @@ -186,6 +242,8 @@ protected: typedef enum {Error, HardDisk, DVDImage, FloppyImage} MediaType; void readMedium(MediaType t, const xml::ElementNode &elmMedium, MediaList &llMedia); void readMediaRegistry(const xml::ElementNode &elmMediaRegistry, MediaRegistry &mr); + void readNATForwardRuleList(const xml::ElementNode &elmParent, NATRuleList &llRules); + void readNATLoopbacks(const xml::ElementNode &elmParent, NATLoopbackOffsetList &llLoopBacks); void setVersionAttribute(xml::ElementNode &elm); void createStubDocument(); @@ -200,6 +258,8 @@ protected: uint32_t level); void buildMediaRegistry(xml::ElementNode &elmParent, const MediaRegistry &mr); + void buildNATForwardRuleList(xml::ElementNode &elmParent, const NATRuleList &natRuleList); + void buildNATLoopbacks(xml::ElementNode &elmParent, const NATLoopbackOffsetList &natLoopbackList); void clearDocument(); struct Data; @@ -223,6 +283,11 @@ struct SystemProperties { SystemProperties() : ulLogHistoryCount(3) +#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) + , fExclusiveHwVirt(false) +#else + , fExclusiveHwVirt(true) +#endif {} com::Utf8Str strDefaultMachineFolder; @@ -233,7 +298,10 @@ struct SystemProperties com::Utf8Str strDefaultVRDEExtPack; com::Utf8Str strAutostartDatabasePath; com::Utf8Str strDefaultAdditionsISO; + com::Utf8Str strDefaultFrontend; + com::Utf8Str strLoggingLevel; uint32_t ulLogHistoryCount; + bool fExclusiveHwVirt; }; struct MachineRegistryEntry @@ -243,6 +311,29 @@ struct MachineRegistryEntry }; typedef std::list MachinesRegistry; +typedef std::map DhcpOptionMap; +typedef DhcpOptionMap::value_type DhcpOptValuePair; +typedef DhcpOptionMap::iterator DhcpOptIterator; +typedef DhcpOptionMap::const_iterator DhcpOptConstIterator; + +typedef struct VmNameSlotKey +{ + VmNameSlotKey(const com::Utf8Str& aVmName, LONG aSlot): VmName(aVmName), + Slot(aSlot){} + const com::Utf8Str VmName; + LONG Slot; + bool operator< (const VmNameSlotKey& that) const + { + if (VmName == that.VmName) + return Slot < that.Slot; + else return VmName < that.VmName; + } +} VmNameSlotKey; +typedef std::map VmSlot2OptionsMap; +typedef VmSlot2OptionsMap::value_type VmSlot2OptionsPair; +typedef VmSlot2OptionsMap::iterator VmSlot2OptionsIterator; +typedef VmSlot2OptionsMap::const_iterator VmSlot2OptionsConstIterator; + struct DHCPServer { DHCPServer() @@ -251,13 +342,45 @@ struct DHCPServer com::Utf8Str strNetworkName, strIPAddress, - strIPNetworkMask, strIPLower, strIPUpper; bool fEnabled; + std::map GlobalDhcpOptions; + VmSlot2OptionsMap VmSlot2OptionsM; }; typedef std::list DHCPServersList; + +/** + * Nat Networking settings (NAT service). + */ +struct NATNetwork +{ + com::Utf8Str strNetworkName; + bool fEnabled; + com::Utf8Str strNetwork; + bool fIPv6; + com::Utf8Str strIPv6Prefix; + uint32_t u32HostLoopback6Offset; + NATLoopbackOffsetList llHostLoopbackOffsetList; + bool fAdvertiseDefaultIPv6Route; + bool fNeedDhcpServer; + NATRuleList llPortForwardRules4; + NATRuleList llPortForwardRules6; + NATNetwork():fEnabled(true), + fAdvertiseDefaultIPv6Route(false), + fNeedDhcpServer(true) + {} + bool operator==(const NATNetwork &n) const + { + return strNetworkName == n.strNetworkName + && strNetwork == n.strNetwork; + } + +}; +typedef std::list NATNetworksList; + + class MainConfigFile : public ConfigFileBase { public: @@ -265,6 +388,8 @@ public: void readMachineRegistry(const xml::ElementNode &elmMachineRegistry); void readDHCPServers(const xml::ElementNode &elmDHCPServers); + void readDhcpOptions(DhcpOptionMap& map, const xml::ElementNode& options); + void readNATNetworks(const xml::ElementNode &elmNATNetworks); void write(const com::Utf8Str strFilename); @@ -273,7 +398,11 @@ public: MediaRegistry mediaRegistry; MachinesRegistry llMachines; DHCPServersList llDhcpServers; + NATNetworksList llNATNetworks; StringsMap mapExtraDataItems; + +private: + void bumpSettingsVersionIfNeeded(); }; //////////////////////////////////////////////////////////////////////////////// @@ -348,43 +477,27 @@ struct BIOSSettings struct USBController { USBController() - : fEnabled(false), - fEnabledEHCI(false) + : enmType(USBControllerType_Null) {} bool operator==(const USBController &u) const; - bool fEnabled; - bool fEnabledEHCI; - USBDeviceFiltersList llDeviceFilters; + com::Utf8Str strName; + USBControllerType_T enmType; }; +typedef std::list USBControllerList; - struct NATRule - { - NATRule() - : proto(NATProtocol_TCP), - u16HostPort(0), - u16GuestPort(0) - {} +struct USB +{ + USB() {} - bool operator==(const NATRule &r) const - { - return strName == r.strName - && proto == r.proto - && u16HostPort == r.u16HostPort - && strHostIP == r.strHostIP - && u16GuestPort == r.u16GuestPort - && strGuestIP == r.strGuestIP; - } + bool operator==(const USB &u) const; - com::Utf8Str strName; - NATProtocol_T proto; - uint16_t u16HostPort; - com::Utf8Str strHostIP; - uint16_t u16GuestPort; - com::Utf8Str strGuestIP; - }; - typedef std::list NATRuleList; + /** List of USB controllers present. */ + USBControllerList llUSBControllers; + /** List of USB device filters. */ + USBDeviceFiltersList llDeviceFilters; +}; struct NAT { @@ -441,6 +554,7 @@ struct USBController bool fAliasUseSamePorts; NATRuleList llRules; }; + /** * NOTE: If you add any fields in here, you must update a) the constructor and b) * the operator== which is used by MachineConfigFile::operator==(), or otherwise @@ -480,6 +594,7 @@ struct NetworkAdapter com::Utf8Str strInternalNetworkName; com::Utf8Str strGenericDriver; StringsMap genericProperties; + com::Utf8Str strNATNetworkName; uint32_t ulBootPriority; com::Utf8Str strBandwidthGroup; // requires settings version 1.13 (VirtualBox 4.2) }; @@ -754,13 +869,16 @@ struct Hardware com::Guid uuid; // hardware uuid, optional (null). bool fHardwareVirt, - fHardwareVirtExclusive, fNestedPaging, fLargePages, fVPID, + fUnrestrictedExecution, fHardwareVirtForce, fSyntheticCpu, + fTripleFaultReset, fPAE; + typedef enum LongModeType { LongMode_Enabled, LongMode_Disabled, LongMode_Legacy } LongModeType; + LongModeType enmLongMode; uint32_t cCPUs; bool fCpuHotPlug; // requires settings version 1.10 (VirtualBox 3.2) CpuList llCpus; // requires settings version 1.10 (VirtualBox 3.2) @@ -773,14 +891,20 @@ struct Hardware BootOrderMap mapBootOrder; // item 0 has highest priority + GraphicsControllerType_T graphicsControllerType; uint32_t ulVRAMSizeMB; uint32_t cMonitors; bool fAccelerate3D, fAccelerate2DVideo; // requires settings version 1.8 (VirtualBox 3.1) - uint32_t ulVideoCaptureHorzRes; - uint32_t ulVideoCaptureVertRes; - bool fVideoCaptureEnabled; - com::Utf8Str strVideoCaptureFile; + + uint32_t ulVideoCaptureHorzRes; // requires settings version 1.14 (VirtualBox 4.3) + uint32_t ulVideoCaptureVertRes; // requires settings version 1.14 (VirtualBox 4.3) + uint32_t ulVideoCaptureRate; // requires settings version 1.14 (VirtualBox 4.3) + uint32_t ulVideoCaptureFPS; // requires settings version 1.14 (VirtualBox 4.3) + bool fVideoCaptureEnabled; // requires settings version 1.14 (VirtualBox 4.3) + uint64_t u64VideoCaptureScreens; // requires settings version 1.14 (VirtualBox 4.3) + com::Utf8Str strVideoCaptureFile; // requires settings version 1.14 (VirtualBox 4.3) + FirmwareType_T firmwareType; // requires settings version 1.9 (VirtualBox 3.1) PointingHIDType_T pointingHIDType; // requires settings version 1.10 (VirtualBox 3.2) @@ -793,7 +917,7 @@ struct Hardware VRDESettings vrdeSettings; BIOSSettings biosSettings; - USBController usbController; + USB usbSettings; NetworkAdaptersList llNetworkAdapters; SerialPortsList llSerialPorts; ParallelPortsList llParallelPorts; @@ -813,6 +937,8 @@ struct Hardware IOSettings ioSettings; // requires settings version 1.10 (VirtualBox 3.2) HostPCIDeviceAttachmentList pciAttachments; // requires settings version 1.12 (VirtualBox 4.1) + + com::Utf8Str strDefaultFrontend; // requires settings version 1.14 (VirtualBox 4.3) }; /** @@ -853,6 +979,9 @@ struct AttachedDevice // Whether the medium supports discarding unused blocks: bool fDiscard; + // Whether the medium is hot-pluggable: + bool fHotPluggable; + int32_t lPort; int32_t lDevice; @@ -1045,7 +1174,8 @@ struct MachineUserData && (uFaultToleranceInterval == c.uFaultToleranceInterval) && (strFaultToleranceAddress == c.strFaultToleranceAddress) && (strFaultTolerancePassword == c.strFaultTolerancePassword) - && (fRTCUseUTC == c.fRTCUseUTC); + && (fRTCUseUTC == c.fRTCUseUTC) + && (ovIcon == c.ovIcon); } com::Utf8Str strName; @@ -1065,6 +1195,7 @@ struct MachineUserData com::Utf8Str strFaultTolerancePassword; uint32_t uFaultToleranceInterval; bool fRTCUseUTC; + com::Utf8Str ovIcon; }; /** @@ -1112,7 +1243,7 @@ public: enum { BuildMachineXML_IncludeSnapshots = 0x01, - BuildMachineXML_WriteVboxVersionAttribute = 0x02, + BuildMachineXML_WriteVBoxVersionAttribute = 0x02, BuildMachineXML_SkipRemovableMedia = 0x04, BuildMachineXML_MediaRegistry = 0x08, BuildMachineXML_SuppressSavedState = 0x10 @@ -1142,7 +1273,7 @@ private: void readDebugging(const xml::ElementNode *pElmDbg, Debugging *pDbg); void readAutostart(const xml::ElementNode *pElmAutostart, Autostart *pAutostart); void readGroups(const xml::ElementNode *elmGroups, StringsList *pllGroups); - void readSnapshot(const xml::ElementNode &elmSnapshot, Snapshot &snap); + bool readSnapshot(const com::Guid &curSnapshotUuid, uint32_t depth, const xml::ElementNode &elmSnapshot, Snapshot &snap); void convertOldOSType_pre1_5(com::Utf8Str &str); void readMachine(const xml::ElementNode &elmMachine); @@ -1155,7 +1286,7 @@ private: void buildDebuggingXML(xml::ElementNode *pElmParent, const Debugging *pDbg); void buildAutostartXML(xml::ElementNode *pElmParent, const Autostart *pAutostart); void buildGroupsXML(xml::ElementNode *pElmParent, const StringsList *pllGroups); - void buildSnapshotXML(xml::ElementNode &elmParent, const Snapshot &snap); + void buildSnapshotXML(uint32_t depth, xml::ElementNode &elmParent, const Snapshot &snap); void bumpSettingsVersionIfNeeded(); }; diff --git a/include/VBox/shflsvc.h b/include/VBox/shflsvc.h index 923e25a7..8d2d7344 100644 --- a/include/VBox/shflsvc.h +++ b/include/VBox/shflsvc.h @@ -3,7 +3,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; @@ -219,6 +219,12 @@ DECLINLINE(bool) ShflStringIsValid(PCSHFLSTRING pString, uint32_t cbBuf) return false; if (RT_UNLIKELY(pString->u16Length >= pString->u16Size)) return false; + /** @todo r=bird: Check that u16Length is a multiple of two if UTF-16 input? */ + /** @todo r=bird: Do we require the string to have a NUL terminator char, if + * so check for it!! (Just had a problem with too small (/2) u16Length + * and code behaving incorrectly because it worked up to the terminator + * instead of the length.) */ + /** @todo r=bird: Who checks for valid UTF-8 encoding of strings? */ return true; } @@ -1338,9 +1344,14 @@ typedef struct _VBoxSFSymlink * Host call, no guest structure is used. */ +/** mapping is writable */ #define SHFL_ADD_MAPPING_F_WRITABLE (RT_BIT_32(0)) +/** mapping is automounted by the guest */ #define SHFL_ADD_MAPPING_F_AUTOMOUNT (RT_BIT_32(1)) +/** allow the guest to create symlinks */ #define SHFL_ADD_MAPPING_F_CREATE_SYMLINKS (RT_BIT_32(2)) +/** mapping is actually missing on the host */ +#define SHFL_ADD_MAPPING_F_MISSING (RT_BIT_32(3)) #define SHFL_CPARMS_ADD_MAPPING (3) diff --git a/include/VBox/sup.h b/include/VBox/sup.h index 5913ff9c..7f94ccab 100644 --- a/include/VBox/sup.h +++ b/include/VBox/sup.h @@ -3,7 +3,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; @@ -423,8 +423,8 @@ typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR; */ /** @see VMMR0_DO_RAW_RUN. */ #define SUP_VMMR0_DO_RAW_RUN 0 -/** @see VMMR0_DO_HWACC_RUN. */ -#define SUP_VMMR0_DO_HWACC_RUN 1 +/** @see VMMR0_DO_HM_RUN. */ +#define SUP_VMMR0_DO_HM_RUN 1 /** @see VMMR0_DO_NOP */ #define SUP_VMMR0_DO_NOP 2 /** @} */ @@ -745,7 +745,8 @@ DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int /** * Initializes the support library. - * Each successful call to SUPR3Init() must be countered by a + * + * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a * call to SUPR3Term(false). * * @returns VBox status code. @@ -753,6 +754,19 @@ DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int */ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession); + +/** + * Initializes the support library, extended version. + * + * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a + * call to SUPR3Term(false). + * + * @returns VBox status code. + * @param fUnrestricted The desired access. + * @param ppSession Where to store the session handle. Defaults to NULL. + */ +SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession); + /** * Terminates the support library. * @@ -1280,6 +1294,13 @@ SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr); */ SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2, uintptr_t uArg3, uintptr_t uArg4); +/** + * Resume built-in keyboard on MacBook Air and Pro hosts. + * + * @returns VBox status code. + */ +SUPR3DECL(int) SUPR3ResumeSuspendedKeyboards(void); + /** @} */ #endif /* IN_RING3 */ @@ -1362,6 +1383,8 @@ SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession); SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...); SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void); SUPR0DECL(int) SUPR0EnableVTx(bool fEnable); +SUPR0DECL(bool) SUPR0SuspendVTxOnCpu(void); +SUPR0DECL(void) SUPR0ResumeVTxOnCpu(bool fSuspended); /** @name Absolute symbols * Take the address of these, don't try call them. diff --git a/include/VBox/types.h b/include/VBox/types.h index 9abf5b6b..4caa5821 100644 --- a/include/VBox/types.h +++ b/include/VBox/types.h @@ -3,7 +3,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; @@ -348,6 +348,11 @@ typedef union PDMCRITSECT *PPDMCRITSECT; /** Pointer to a const PDM critical section. */ typedef const union PDMCRITSECT *PCPDMCRITSECT; +/** Pointer to a PDM read/write critical section. */ +typedef union PDMCRITSECTRW *PPDMCRITSECTRW; +/** Pointer to a const PDM read/write critical section. */ +typedef union PDMCRITSECTRW const *PCPDMCRITSECTRW; + /** R3 pointer to a timer. */ typedef R3PTRTYPE(struct TMTIMER *) PTMTIMERR3; /** Pointer to a R3 pointer to a timer. */ diff --git a/include/VBox/usb.h b/include/VBox/usb.h index db648c7a..4ab531a0 100644 --- a/include/VBox/usb.h +++ b/include/VBox/usb.h @@ -3,7 +3,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/include/VBox/usbfilter.h b/include/VBox/usbfilter.h index 1ed209fd..45c3151c 100644 --- a/include/VBox/usbfilter.h +++ b/include/VBox/usbfilter.h @@ -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; diff --git a/include/VBox/usblib-darwin.h b/include/VBox/usblib-darwin.h index db43e743..d46a9e28 100644 --- a/include/VBox/usblib-darwin.h +++ b/include/VBox/usblib-darwin.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007 Oracle Corporation + * Copyright (C) 2007-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; diff --git a/include/VBox/usblib-solaris.h b/include/VBox/usblib-solaris.h index f8c4b4c2..053c326a 100644 --- a/include/VBox/usblib-solaris.h +++ b/include/VBox/usblib-solaris.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 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; @@ -126,6 +126,7 @@ typedef struct VUSBXFERTYPE enmType; /* Xfer type */ VUSBDIRECTION enmDir; /* Xfer direction */ VUSBSTATUS enmStatus; /* URB status */ + bool fShortOk; /* Whether receiving less data than requested is acceptable. */ size_t cbData; /* Size of the data */ void *pvData; /* Pointer to the data */ uint32_t cIsocPkts; /* Number of Isoc packets */ @@ -153,8 +154,11 @@ typedef struct typedef enum { - VBOXUSB_RESET_LEVEL_NONE = 0, + /** Close device not a reset. */ + VBOXUSB_RESET_LEVEL_CLOSE = 0, + /** Hard reset resulting in device replug behaviour. */ VBOXUSB_RESET_LEVEL_REATTACH = 2, + /** Device-level reset. */ VBOXUSB_RESET_LEVEL_SOFT = 4 } VBOXUSB_RESET_LEVEL; diff --git a/include/VBox/usblib-win.h b/include/VBox/usblib-win.h index ed8885bb..193bde75 100644 --- a/include/VBox/usblib-win.h +++ b/include/VBox/usblib-win.h @@ -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/include/VBox/usblib.h b/include/VBox/usblib.h index 21d46419..5d00af68 100644 --- a/include/VBox/usblib.h +++ b/include/VBox/usblib.h @@ -3,7 +3,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/include/VBox/various.sed b/include/VBox/various.sed index fb3507f1..3cbb69a7 100644 --- a/include/VBox/various.sed +++ b/include/VBox/various.sed @@ -3,6 +3,13 @@ /ASM-INC/basm-inc /ASM-NOINC/basm-noinc +# Newline escapes. +:check-newline-escape +/\\$/!bno-more-newline-escapes +N +b check-newline-escape +:no-more-newline-escapes + # Strip comments and trailing space. s/[[:space:]][[:space:]]*\/\*.*$//g s/[[:space:]][[:space:]]*\/\/.*$//g diff --git a/include/VBox/vd-cache-plugin.h b/include/VBox/vd-cache-plugin.h index af185680..c8a37535 100644 --- a/include/VBox/vd-cache-plugin.h +++ b/include/VBox/vd-cache-plugin.h @@ -3,7 +3,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; @@ -131,43 +131,63 @@ typedef struct VDCACHEBACKEND DECLR3CALLBACKMEMBER(int, pfnClose, (void *pBackendData, bool fDelete)); /** - * Read data from a cache image. The area read never crosses a block - * boundary. + * Start a read request. * * @returns VBox status code. - * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start reading from. - * @param pvBuf Where to store the read bits. - * @param cbRead Number of bytes to read. + * @param uOffset The offset of the virtual disk to read from. + * @param cbRead How many bytes to read. + * @param pIoCtx I/O context associated with this request. * @param pcbActuallyRead Pointer to returned number of bytes read. */ - DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, void *pvBuf, - size_t cbRead, size_t *pcbActuallyRead)); + DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, + PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); /** - * Write data to a cache image. The area written never crosses a block - * boundary. + * Start a write request. * * @returns VBox status code. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start writing to. - * @param pvBuf Where to retrieve the written bits. - * @param cbWrite Number of bytes to write. + * @param uOffset The offset of the virtual disk to write to. + * @param cbWrite How many bytes to write. + * @param pIoCtx I/O context associated with this request. * @param pcbWriteProcess Pointer to returned number of bytes that could - * be processed. + * be processed. In case the function returned + * VERR_VD_BLOCK_FREE this is the number of bytes + * that could be written in a full block write, + * when prefixed/postfixed by the appropriate + * amount of (previously read) padding data. */ - DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, - const void *pvBuf, size_t cbWrite, - size_t *pcbWriteProcess)); + DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, + PVDIOCTX pIoCtx, size_t *pcbWriteProcess)); /** * Flush data to disk. * * @returns VBox status code. * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. */ - DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData)); + DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData, PVDIOCTX pIoCtx)); + + /** + * Discards the given amount of bytes from the cache. + * + * @returns VBox status code. + * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment + * for the discard. + * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. + * @param uOffset The offset of the first byte to discard. + * @param cbDiscard How many bytes to discard. + */ + DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData, PVDIOCTX pIoCtx, + uint64_t uOffset, size_t cbDiscard, + size_t *pcbPreAllocated, + size_t *pcbPostAllocated, + size_t *pcbActuallyDiscarded, + void **ppbmAllocationBitmap, + unsigned fDiscard)); /** * Get the version of a cache image. @@ -283,46 +303,6 @@ typedef struct VDCACHEBACKEND */ DECLR3CALLBACKMEMBER(void, pfnDump, (void *pBackendData)); - /** - * Start an asynchronous read request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to read from. - * @param cbRead How many bytes to read. - * @param pIoCtx I/O context associated with this request. - * @param pcbActuallyRead Pointer to returned number of bytes read. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, - PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); - - /** - * Start an asynchronous write request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to write to. - * @param cbWrite How many bytes to write. - * @param pIoCtx I/O context associated with this request. - * @param pcbWriteProcess Pointer to returned number of bytes that could - * be processed. In case the function returned - * VERR_VD_BLOCK_FREE this is the number of bytes - * that could be written in a full block write, - * when prefixed/postfixed by the appropriate - * amount of (previously read) padding data. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, - PVDIOCTX pIoCtx, size_t *pcbWriteProcess)); - - /** - * Flush data to disk. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param pIoCtx I/O context associated with this request. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncFlush, (void *pBackendData, PVDIOCTX pIoCtx)); - /** Returns a human readable hard disk location string given a * set of hard disk configuration keys. The returned string is an * equivalent of the full file path for image-based hard disks. diff --git a/include/VBox/vd-ifs-internal.h b/include/VBox/vd-ifs-internal.h index 5b5ae5ad..41c551f2 100644 --- a/include/VBox/vd-ifs-internal.h +++ b/include/VBox/vd-ifs-internal.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -209,84 +209,39 @@ typedef struct VDINTERFACEIOINT uint64_t cbSize)); /** - * Synchronous write callback. - * - * @return VBox status code. - * @param pvUser The opaque data passed on container creation. - * @param pStorage The storage handle to use. - * @param uOffset The offset to start from. - * @param pvBuffer Pointer to the bits need to be written. - * @param cbBuffer How many bytes to write. - * @param pcbWritten Where to store how many bytes were actually written. - * - * @notes Do not use in code called from the async read/write entry points in the backends. - * This should be only used during open/close of images and for the support functions - * which are not called while a VM is running (pfnCompact). - */ - DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset, - const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten)); - - /** - * Synchronous read callback. - * - * @return VBox status code. - * @param pvUser The opaque data passed on container creation. - * @param pStorage The storage handle to use. - * @param uOffset The offset to start from. - * @param pvBuffer Where to store the read bits. - * @param cbBuffer How many bytes to read. - * @param pcbRead Where to store how many bytes were actually read. - * - * @notes See pfnWriteSync() - */ - DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset, - void *pvBuffer, size_t cbBuffer, size_t *pcbRead)); - - /** - * Flush data to the storage backend. - * - * @return VBox status code. - * @param pvUser The opaque data passed on container creation. - * @param pStorage The storage handle to flush. - * - * @notes See pfnWriteSync() - */ - DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, PVDIOSTORAGE pStorage)); - - /** - * Initiate an asynchronous read request for user data. + * Initiate a read request for user data. * * @return VBox status code. * @param pvUser The opaque user data passed on container creation. * @param pStorage The storage handle. * @param uOffset The offset to start reading from. - * @param pIoCtx I/O context passed in VDAsyncRead/Write. + * @param pIoCtx I/O context passed in the read/write callback. * @param cbRead How many bytes to read. */ - DECLR3CALLBACKMEMBER(int, pfnReadUserAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, - size_t cbRead)); + DECLR3CALLBACKMEMBER(int, pfnReadUser, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, + size_t cbRead)); /** - * Initiate an asynchronous write request for user data. + * Initiate a write request for user data. * * @return VBox status code. * @param pvUser The opaque user data passed on container creation. * @param pStorage The storage handle. * @param uOffset The offset to start writing to. - * @param pIoCtx I/O context passed in VDAsyncRead/Write + * @param pIoCtx I/O context passed in the read/write callback. * @param cbWrite How many bytes to write. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. */ - DECLR3CALLBACKMEMBER(int, pfnWriteUserAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, - size_t cbWrite, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnWriteUser, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, + size_t cbWrite, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** - * Reads metadata asynchronously from storage. + * Reads metadata from storage. * The current I/O context will be halted. * * @returns VBox status code. @@ -299,16 +254,23 @@ typedef struct VDINTERFACEIOINT * @param ppMetaXfer Where to store the metadata transfer handle on success. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. + * + * @notes If pIoCtx is NULL the metadata read is handled synchronously + * i.e. the call returns only if the data is available in the given + * buffer. ppMetaXfer, pfnCompleted and pvCompleteUser are ignored in that case. + * Use the synchronous version only when opening/closing the image + * or when doing certain operations like resizing, compacting or repairing + * the disk. */ - DECLR3CALLBACKMEMBER(int, pfnReadMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PPVDMETAXFER ppMetaXfer, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnReadMeta, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PPVDMETAXFER ppMetaXfer, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** - * Writes metadata asynchronously to storage. + * Writes metadata to storage. * * @returns VBox status code. * @param pvUser The opaque user data passed on container creation. @@ -319,12 +281,14 @@ typedef struct VDINTERFACEIOINT * @param pIoCtx The I/O context which triggered the write. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. + * + * @notes See pfnReadMeta(). */ - DECLR3CALLBACKMEMBER(int, pfnWriteMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnWriteMeta, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, const void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** * Releases a metadata transfer handle. @@ -337,7 +301,7 @@ typedef struct VDINTERFACEIOINT DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer)); /** - * Initiates an async flush request. + * Initiates a flush request. * * @return VBox status code. * @param pvUser The opaque data passed on container creation. @@ -345,11 +309,13 @@ typedef struct VDINTERFACEIOINT * @param pIoCtx I/O context which triggered the flush. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. + * + * @notes See pfnReadMeta(). */ - DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, PVDIOSTORAGE pStorage, - PVDIOCTX pIoCtx, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pvUser, PVDIOSTORAGE pStorage, + PVDIOCTX pIoCtx, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** * Copies a buffer into the I/O context. @@ -361,7 +327,7 @@ typedef struct VDINTERFACEIOINT * @param cbBuffer Number of bytes to copy. */ DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx, - void *pvBuffer, size_t cbBuffer)); + const void *pvBuffer, size_t cbBuffer)); /** * Copies data from the I/O context into a buffer. @@ -414,6 +380,32 @@ typedef struct VDINTERFACEIOINT */ DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx, int rcReq, size_t cbCompleted)); + + /** + * Returns whether the given I/O context must be treated synchronously. + * + * @returns true if the I/O context must be processed synchronously + * false otherwise. + * @param pvUser The opaque user data passed on container creation. + * @param pIoCtx The I/O context. + */ + DECLR3CALLBACKMEMBER(bool, pfnIoCtxIsSynchronous, (void *pvUser, PVDIOCTX pIoCtx)); + + /** + * Returns whether the user buffer of the I/O context is complete zero + * from to current position upto the given number of bytes. + * + * @returns true if the I/O context user buffer consists solely of zeros + * false otherwise. + * @param pvUser The opaque user data passed on container creation. + * @param pIoCtx The I/O context. + * @param cbCheck Number of bytes to check for zeros. + * @param fAdvance Flag whether to advance the buffer pointer if true + * is returned. + */ + DECLR3CALLBACKMEMBER(bool, pfnIoCtxIsZero, (void *pvUser, PVDIOCTX pIoCtx, + size_t cbCheck, bool fAdvance)); + } VDINTERFACEIOINT, *PVDINTERFACEIOINT; /** @@ -483,64 +475,64 @@ DECLINLINE(int) vdIfIoIntFileSetSize(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pS } DECLINLINE(int) vdIfIoIntFileWriteSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, const void *pvBuffer, size_t cbBuffer, - size_t *pcbWritten) + uint64_t uOffset, const void *pvBuffer, size_t cbBuffer) { - return pIfIoInt->pfnWriteSync(pIfIoInt->Core.pvUser, pStorage, uOffset, - pvBuffer, cbBuffer, pcbWritten); + return pIfIoInt->pfnWriteMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, NULL, + NULL, NULL); } DECLINLINE(int) vdIfIoIntFileReadSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, size_t cbBuffer, - size_t *pcbRead) + uint64_t uOffset, void *pvBuffer, size_t cbBuffer) { - return pIfIoInt->pfnReadSync(pIfIoInt->Core.pvUser, pStorage, uOffset, - pvBuffer, cbBuffer, pcbRead); + return pIfIoInt->pfnReadMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, NULL, + NULL, NULL, NULL); } DECLINLINE(int) vdIfIoIntFileFlushSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage) { - return pIfIoInt->pfnFlushSync(pIfIoInt->Core.pvUser, pStorage); + return pIfIoInt->pfnFlush(pIfIoInt->Core.pvUser, pStorage, NULL, NULL, NULL); } -DECLINLINE(int) vdIfIoIntFileReadUserAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbRead) +DECLINLINE(int) vdIfIoIntFileReadUser(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbRead) { - return pIfIoInt->pfnReadUserAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pIoCtx, cbRead); + return pIfIoInt->pfnReadUser(pIfIoInt->Core.pvUser, pStorage, + uOffset, pIoCtx, cbRead); } -DECLINLINE(int) vdIfIoIntFileWriteUserAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbWrite, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileWriteUser(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbWrite, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) { - return pIfIoInt->pfnWriteUserAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pIoCtx, cbWrite, pfnComplete, - pvCompleteUser); + return pIfIoInt->pfnWriteUser(pIfIoInt->Core.pvUser, pStorage, + uOffset, pIoCtx, cbWrite, pfnComplete, + pvCompleteUser); } -DECLINLINE(int) vdIfIoIntFileReadMetaAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PPVDMETAXFER ppMetaXfer, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileReadMeta(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PPVDMETAXFER ppMetaXfer, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) { - return pIfIoInt->pfnReadMetaAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pvBuffer, cbBuffer, pIoCtx, - ppMetaXfer, pfnComplete, pvCompleteUser); + return pIfIoInt->pfnReadMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, pIoCtx, + ppMetaXfer, pfnComplete, pvCompleteUser); } -DECLINLINE(int) vdIfIoIntFileWriteMetaAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileWriteMeta(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) { - return pIfIoInt->pfnWriteMetaAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pvBuffer, cbBuffer, pIoCtx, - pfnComplete, pvCompleteUser); + return pIfIoInt->pfnWriteMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, pIoCtx, + pfnComplete, pvCompleteUser); } DECLINLINE(void) vdIfIoIntMetaXferRelease(PVDINTERFACEIOINT pIfIoInt, PVDMETAXFER pMetaXfer) @@ -548,12 +540,24 @@ DECLINLINE(void) vdIfIoIntMetaXferRelease(PVDINTERFACEIOINT pIfIoInt, PVDMETAXFE pIfIoInt->pfnMetaXferRelease(pIfIoInt->Core.pvUser, pMetaXfer); } -DECLINLINE(int) vdIfIoIntFileFlushAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - PVDIOCTX pIoCtx, PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileFlush(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + PVDIOCTX pIoCtx, PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) +{ + return pIfIoInt->pfnFlush(pIfIoInt->Core.pvUser, pStorage, pIoCtx, pfnComplete, + pvCompleteUser); +} + +DECLINLINE(size_t) vdIfIoIntIoCtxCopyTo(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + const void *pvBuffer, size_t cbBuffer) +{ + return pIfIoInt->pfnIoCtxCopyTo(pIfIoInt->Core.pvUser, pIoCtx, pvBuffer, cbBuffer); +} + +DECLINLINE(size_t) vdIfIoIntIoCtxCopyFrom(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + void *pvBuffer, size_t cbBuffer) { - return pIfIoInt->pfnFlushAsync(pIfIoInt->Core.pvUser, pStorage, pIoCtx, pfnComplete, - pvCompleteUser); + return pIfIoInt->pfnIoCtxCopyFrom(pIfIoInt->Core.pvUser, pIoCtx, pvBuffer, cbBuffer); } DECLINLINE(size_t) vdIfIoIntIoCtxSet(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, @@ -562,6 +566,25 @@ DECLINLINE(size_t) vdIfIoIntIoCtxSet(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx return pIfIoInt->pfnIoCtxSet(pIfIoInt->Core.pvUser, pIoCtx, ch, cbSet); } +DECLINLINE(size_t) vdIfIoIntIoCtxSegArrayCreate(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + PRTSGSEG paSeg, unsigned *pcSeg, + size_t cbData) +{ + return pIfIoInt->pfnIoCtxSegArrayCreate(pIfIoInt->Core.pvUser, pIoCtx, paSeg, pcSeg, cbData); +} + +DECLINLINE(bool) vdIfIoIntIoCtxIsSynchronous(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx) +{ + return pIfIoInt->pfnIoCtxIsSynchronous(pIfIoInt->Core.pvUser, pIoCtx); +} + +DECLINLINE(bool) vdIfIoIntIoCtxIsZero(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + size_t cbCheck, bool fAdvance) +{ + return pIfIoInt->pfnIoCtxIsZero(pIfIoInt->Core.pvUser, pIoCtx, cbCheck, fAdvance); +} + + RT_C_DECLS_END /** @} */ diff --git a/include/VBox/vd-ifs.h b/include/VBox/vd-ifs.h index d3167a41..9d2d4e43 100644 --- a/include/VBox/vd-ifs.h +++ b/include/VBox/vd-ifs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -307,7 +307,7 @@ DECLINLINE(int) vdIfErrorMessage(PVDINTERFACEERROR pIfError, const char *pszForm int rc = VINF_SUCCESS; va_list va; va_start(va, pszFormat); - if (pIfError) + if (pIfError && pIfError->pfnMessage) rc = pIfError->pfnMessage(pIfError->Core.pvUser, pszFormat, va); va_end(va); return rc; @@ -604,6 +604,43 @@ DECLINLINE(int) vdIfIoFileFlushSync(PVDINTERFACEIO pIfIo, void *pStorage) return pIfIo->pfnFlushSync(pIfIo->Core.pvUser, pStorage); } +/** + * Create a VFS stream handle around a VD I/O interface. + * + * The I/O interface will not be closed or free by the stream, the caller will + * do so after it is done with the stream and has released the instances of the + * I/O stream object returned by this API. + * + * @return VBox status code. + * @param pVDIfsIo Pointer to the VD I/O interface. + * @param pvStorage The storage argument to pass to the interface + * methods. + * @param fFlags RTFILE_O_XXX, access mask requied. + * @param phVfsIos Where to return the VFS I/O stream handle on + * success. + */ +VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos); + +/** + * Create a VFS file handle around a VD I/O interface. + * + * The I/O interface will not be closed or free by the VFS file, the caller will + * do so after it is done with the VFS file and has released the instances of + * the VFS object returned by this API. + * + * @return VBox status code. + * @param pVDIfs Pointer to the VD I/O interface. If NULL, then @a + * pVDIfsInt must be specified. + * @param pVDIfsInt Pointer to the internal VD I/O interface. If NULL, + * then @ pVDIfs must be specified. + * @param pvStorage The storage argument to pass to the interface + * methods. + * @param fFlags RTFILE_O_XXX, access mask requied. + * @param phVfsFile Where to return the VFS file handle on success. + */ +VBOXDDU_DECL(int) VDIfCreateVfsFile(PVDINTERFACEIO pVDIfs, struct VDINTERFACEIOINT *pVDIfsInt, void *pvStorage, uint32_t fFlags, PRTVFSFILE phVfsFile); + + /** * Callback which provides progress information about a currently running * lengthy operation. diff --git a/include/VBox/vd-plugin.h b/include/VBox/vd-plugin.h index 46f1d9a9..1a0ca12d 100644 --- a/include/VBox/vd-plugin.h +++ b/include/VBox/vd-plugin.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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; @@ -174,35 +174,26 @@ typedef struct VBOXHDDBACKEND DECLR3CALLBACKMEMBER(int, pfnClose, (void *pBackendData, bool fDelete)); /** - * Read data from a disk image. The area read never crosses a block - * boundary. + * Start a read request. * * @returns VBox status code. - * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start reading from. - * @param pvBuf Where to store the read bits. - * @param cbRead Number of bytes to read. + * @param uOffset The offset of the virtual disk to read from. + * @param cbRead How many bytes to read. + * @param pIoCtx I/O context associated with this request. * @param pcbActuallyRead Pointer to returned number of bytes read. */ - DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, void *pvBuf, - size_t cbRead, size_t *pcbActuallyRead)); + DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, + PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); /** - * Write data to a disk image. The area written never crosses a block - * boundary. + * Start a write request. * * @returns VBox status code. - * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block and - * this is not a full-block write. The write must be repeated with - * the correct amount of prefix/postfix data read from the images below - * in the image stack. This might not be the most convenient interface, - * but it works with arbitrary block sizes, especially when the image - * stack uses different block sizes. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start writing to. - * @param pvBuf Where to retrieve the written bits. - * @param cbWrite Number of bytes to write. + * @param uOffset The offset of the virtual disk to write to. + * @param cbWrite How many bytes to write. + * @param pIoCtx I/O context associated with this request. * @param pcbWriteProcess Pointer to returned number of bytes that could * be processed. In case the function returned * VERR_VD_BLOCK_FREE this is the number of bytes @@ -216,8 +207,8 @@ typedef struct VBOXHDDBACKEND * @param fWrite Flags which affect write behavior. Combination * of the VD_WRITE_* flags. */ - DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, - const void *pvBuf, size_t cbWrite, + DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, + PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite)); @@ -226,8 +217,41 @@ typedef struct VBOXHDDBACKEND * * @returns VBox status code. * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. */ - DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData)); + DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData, PVDIOCTX pIoCtx)); + + /** + * Discards the given amount of bytes decreasing the size of the image if possible + * + * @returns VBox status code. + * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment + * for the discard. + * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. + * @param uOffset The offset of the first byte to discard. + * @param cbDiscard How many bytes to discard. + * @param pcbPreAllocated Pointer to the returned amount of bytes that must + * be discarded before the range to perform a full + * block discard. + * @param pcbPostAllocated Pointer to the returned amount of bytes that must + * be discarded after the range to perform a full + * block discard. + * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which + * could be actually discarded. + * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap + * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL + * if the allocation bitmap should be returned. + * @param fDiscard Flags which affect discard behavior. Combination + * of the VD_DISCARD_* flags. + */ + DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData, PVDIOCTX pIoCtx, + uint64_t uOffset, size_t cbDiscard, + size_t *pcbPreAllocated, + size_t *pcbPostAllocated, + size_t *pcbActuallyDiscarded, + void **ppbmAllocationBitmap, + unsigned fDiscard)); /** * Get the version of a disk image. @@ -237,6 +261,14 @@ typedef struct VBOXHDDBACKEND */ DECLR3CALLBACKMEMBER(unsigned, pfnGetVersion, (void *pBackendData)); + /** + * Get the sector size of a disk image. + * + * @returns size of disk image in bytes. + * @param pBackendData Opaque state data for this image. + */ + DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize, (void *pBackendData)); + /** * Get the capacity of a disk image. * @@ -464,54 +496,6 @@ typedef struct VBOXHDDBACKEND */ DECLR3CALLBACKMEMBER(int, pfnSetParentFilename, (void *pBackendData, const char *pszParentFilename)); - /** - * Start an asynchronous read request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to read from. - * @param cbRead How many bytes to read. - * @param pIoCtx I/O context associated with this request. - * @param pcbActuallyRead Pointer to returned number of bytes read. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, - PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); - - /** - * Start an asynchronous write request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to write to. - * @param cbWrite How many bytes to write. - * @param pIoCtx I/O context associated with this request. - * @param pcbWriteProcess Pointer to returned number of bytes that could - * be processed. In case the function returned - * VERR_VD_BLOCK_FREE this is the number of bytes - * that could be written in a full block write, - * when prefixed/postfixed by the appropriate - * amount of (previously read) padding data. - * @param pcbPreRead Pointer to the returned amount of data that must - * be prefixed to perform a full block write. - * @param pcbPostRead Pointer to the returned amount of data that must - * be postfixed to perform a full block write. - * @param fWrite Flags which affect write behavior. Combination - * of the VD_WRITE_* flags. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, - PVDIOCTX pIoCtx, - size_t *pcbWriteProcess, size_t *pcbPreRead, - size_t *pcbPostRead, unsigned fWrite)); - - /** - * Flush data to disk. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param pIoCtx I/O context associated with this request. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncFlush, (void *pBackendData, PVDIOCTX pIoCtx)); - /** Returns a human readable hard disk location string given a * set of hard disk configuration keys. The returned string is an * equivalent of the full file path for image-based hard disks. @@ -569,70 +553,6 @@ typedef struct VBOXHDDBACKEND PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation)); - /** - * Discards the given amount of bytes decreasing the size of the image if possible. - * - * @returns VBox status code. - * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment - * for the discard. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the first byte to discard. - * @param cbDiscard How many bytes to discard. - * @param pcbPreAllocated Pointer to the returned amount of bytes that must - * be discarded before the range to perform a full - * block discard. - * @param pcbPostAllocated Pointer to the returned amount of bytes that must - * be discarded after the range to perform a full - * block discard. - * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which - * could be actually discarded. - * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap - * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL - * if the allocation bitmap should be returned. - * @param fDiscard Flags which affect discard behavior. Combination - * of the VD_DISCARD_* flags. - */ - DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData, - uint64_t uOffset, size_t cbDiscard, - size_t *pcbPreAllocated, - size_t *pcbPostAllocated, - size_t *pcbActuallyDiscarded, - void **ppbmAllocationBitmap, - unsigned fDiscard)); - - /** - * Discards the given amount of bytes decreasing the size of the image if possible - * callback version for asynchronous I/O. - * - * @returns VBox status code. - * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment - * for the discard. - * @param pBackendData Opaque state data for this image. - * @param pIoCtx I/O context associated with this request. - * @param uOffset The offset of the first byte to discard. - * @param cbDiscard How many bytes to discard. - * @param pcbPreAllocated Pointer to the returned amount of bytes that must - * be discarded before the range to perform a full - * block discard. - * @param pcbPostAllocated Pointer to the returned amount of bytes that must - * be discarded after the range to perform a full - * block discard. - * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which - * could be actually discarded. - * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap - * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL - * if the allocation bitmap should be returned. - * @param fDiscard Flags which affect discard behavior. Combination - * of the VD_DISCARD_* flags. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncDiscard, (void *pBackendData, PVDIOCTX pIoCtx, - uint64_t uOffset, size_t cbDiscard, - size_t *pcbPreAllocated, - size_t *pcbPostAllocated, - size_t *pcbActuallyDiscarded, - void **ppbmAllocationBitmap, - unsigned fDiscard)); - /** * Try to repair the given image. * diff --git a/include/VBox/vd.h b/include/VBox/vd.h index 86589bbf..ba0768eb 100644 --- a/include/VBox/vd.h +++ b/include/VBox/vd.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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; @@ -151,14 +151,14 @@ typedef struct VBOXHDDRAWPARTDESC } VBOXHDDRAWPARTDESC, *PVBOXHDDRAWPARTDESC; /** - * Auxiliary data structure for difference between GPT and MBR - * disks. + * Auxiliary data structure for difference between GPT and MBR + * disks. */ -enum PARTITIONING_TYPE +typedef enum VBOXHDDPARTTYPE { MBR, GPT -}; +} VBOXHDDPARTTYPE; /** * Auxiliary data structure for creating raw disks. @@ -178,8 +178,8 @@ typedef struct VBOXHDDRAW unsigned cPartDescs; /** Pointer to the partition descriptor array. */ PVBOXHDDRAWPARTDESC pPartDescs; - /**partitioning type of the disk */ - PARTITIONING_TYPE uPartitioningType; + /** Partitioning type of the disk */ + VBOXHDDPARTTYPE uPartitioningType; } VBOXHDDRAW, *PVBOXHDDRAW; @@ -230,8 +230,14 @@ typedef struct VBOXHDDRAW * sector at a time is the safest solution. */ #define VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS RT_BIT(9) +/** + * Don't do unnecessary consistency checks when opening the image. + * Only valid when the image is opened in readonly because inconsistencies + * can lead to corrupted images in read-write mode. + */ +#define VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS RT_BIT(10) /** Mask of valid flags. */ -#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_DISCARD | VD_OPEN_FLAGS_IGNORE_FLUSH | VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS) +#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_DISCARD | VD_OPEN_FLAGS_IGNORE_FLUSH | VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS) /** @}*/ /** @@ -789,7 +795,9 @@ VBOXDDU_DECL(int) VDCompact(PVBOXHDD pDisk, unsigned nImage, PVDINTERFACE pVDIfsOperation); /** - * Resizes the given disk image to the given size. + * Resizes the given disk image to the given size. It is OK if there are + * multiple images open in the container. In this case the last disk image + * will be resized. * * @return VBox status * @return VERR_VD_IMAGE_READ_ONLY if image is not writable. @@ -891,6 +899,16 @@ VBOXDDU_DECL(unsigned) VDGetCount(PVBOXHDD pDisk); */ VBOXDDU_DECL(bool) VDIsReadOnly(PVBOXHDD pDisk); +/** + * Get sector size of an image in HDD container. + * + * @return Virtual disk sector size in bytes. + * @return 0 if image with specified number was not opened. + * @param pDisk Pointer to HDD container. + * @param nImage Image number, counts from 0. 0 is always base image of container. + */ +VBOXDDU_DECL(uint32_t) VDGetSectorSize(PVBOXHDD pDisk, unsigned nImage); + /** * Get total capacity of an image in HDD container. * @@ -1239,7 +1257,8 @@ VBOXDDU_DECL(int) VDRepair(PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, * @return VBox status code. * @param pDisk Pointer to HDD container. * @param fFlags Combination of the VD_VFSFILE_* flags. - * @param phVfsFile Where to stoer the handle to the VFS file on success. + * @param phVfsFile Where to store the handle to the VFS file on + * success. */ VBOXDDU_DECL(int) VDCreateVfsFileFromDisk(PVBOXHDD pDisk, uint32_t fFlags, PRTVFSFILE phVfsFile); diff --git a/include/VBox/version.h b/include/VBox/version.h index 8a48c1f6..defa3219 100644 --- a/include/VBox/version.h +++ b/include/VBox/version.h @@ -3,7 +3,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/include/VBox/vmm/cfgm.h b/include/VBox/vmm/cfgm.h index 9b4e47ab..dbc8e527 100644 --- a/include/VBox/vmm/cfgm.h +++ b/include/VBox/vmm/cfgm.h @@ -3,7 +3,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; @@ -74,19 +74,20 @@ typedef enum CFGMCONFIGTYPE * can make any necessary per-thread initializations at this point. * * @returns VBox status code. - * @param pVM VM handle. + * @param pUVM The user mode VM handle. + * @param pVM The shared VM handle. * @param pvUser The argument supplied to VMR3Create(). */ -typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PVM pVM, void *pvUser); +typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PUVM pUVM, PVM pVM, void *pvUser); /** Pointer to a FNCFGMCONSTRUCTOR(). */ typedef FNCFGMCONSTRUCTOR *PFNCFGMCONSTRUCTOR; VMMR3DECL(int) CFGMR3Init(PVM pVM, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUser); VMMR3DECL(int) CFGMR3Term(PVM pVM); - - -VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PVM pVM); VMMR3DECL(int) CFGMR3ConstructDefaultTree(PVM pVM); + +VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PUVM pUVM); +VMMR3DECL(int) CFGMR3DestroyTree(PCFGMNODE pRoot); VMMR3DECL(void) CFGMR3Dump(PCFGMNODE pRoot); VMMR3DECL(int) CFGMR3DuplicateSubTree(PCFGMNODE pRoot, PCFGMNODE *ppCopy); VMMR3DECL(int) CFGMR3ReplaceSubTree(PCFGMNODE pRoot, PCFGMNODE pNewRoot); @@ -185,6 +186,7 @@ VMMR3DECL(int) CFGMR3QueryStringAllocDef(PCFGMNODE pNode, const char *p * @{ */ VMMR3DECL(PCFGMNODE) CFGMR3GetRoot(PVM pVM); +VMMR3DECL(PCFGMNODE) CFGMR3GetRootU(PUVM pUVM); VMMR3DECL(PCFGMNODE) CFGMR3GetParent(PCFGMNODE pNode); VMMR3DECL(PCFGMNODE) CFGMR3GetParentEx(PVM pVM, PCFGMNODE pNode); VMMR3DECL(PCFGMNODE) CFGMR3GetChild(PCFGMNODE pNode, const char *pszPath); diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h index 0b4abf33..d3ca4c02 100644 --- a/include/VBox/vmm/cpum.h +++ b/include/VBox/vmm/cpum.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -77,13 +77,259 @@ typedef enum CPUMCPUVENDOR CPUMCPUVENDOR_INTEL, CPUMCPUVENDOR_AMD, CPUMCPUVENDOR_VIA, + CPUMCPUVENDOR_CYRIX, CPUMCPUVENDOR_UNKNOWN, - CPUMCPUVENDOR_SYNTHETIC, /** 32bit hackishness. */ CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff } CPUMCPUVENDOR; +/** + * X86 and AMD64 CPU microarchitectures and in processor generations. + * + * @remarks The separation here is sometimes a little bit too finely grained, + * and the differences is more like processor generation than micro + * arch. This can be useful, so we'll provide functions for getting at + * more coarse grained info. + */ +typedef enum CPUMMICROARCH +{ + kCpumMicroarch_Invalid = 0, + + kCpumMicroarch_Intel_First, + + kCpumMicroarch_Intel_8086 = kCpumMicroarch_Intel_First, + kCpumMicroarch_Intel_80186, + kCpumMicroarch_Intel_80286, + kCpumMicroarch_Intel_80386, + kCpumMicroarch_Intel_80486, + kCpumMicroarch_Intel_P5, + + kCpumMicroarch_Intel_P6_Core_Atom_First, + kCpumMicroarch_Intel_P6 = kCpumMicroarch_Intel_P6_Core_Atom_First, + kCpumMicroarch_Intel_P6_II, + kCpumMicroarch_Intel_P6_III, + + kCpumMicroarch_Intel_P6_M_Banias, + kCpumMicroarch_Intel_P6_M_Dothan, + kCpumMicroarch_Intel_Core_Yonah, /**< Core, also known as Enhanced Pentium M. */ + + kCpumMicroarch_Intel_Core2_First, + kCpumMicroarch_Intel_Core2_Merom = kCpumMicroarch_Intel_Core2_First, + kCpumMicroarch_Intel_Core2_Penryn, + + kCpumMicroarch_Intel_Core7_First, + kCpumMicroarch_Intel_Core7_Nehalem = kCpumMicroarch_Intel_Core7_First, + kCpumMicroarch_Intel_Core7_Westmere, + kCpumMicroarch_Intel_Core7_SandyBridge, + kCpumMicroarch_Intel_Core7_IvyBridge, + kCpumMicroarch_Intel_Core7_Haswell, + kCpumMicroarch_Intel_Core7_Broadwell, + kCpumMicroarch_Intel_Core7_Skylake, + kCpumMicroarch_Intel_Core7_Cannonlake, + kCpumMicroarch_Intel_Core7_End, + + kCpumMicroarch_Intel_Atom_First, + kCpumMicroarch_Intel_Atom_Bonnell = kCpumMicroarch_Intel_Atom_First, + kCpumMicroarch_Intel_Atom_Lincroft, /**< Second generation bonnell (44nm). */ + kCpumMicroarch_Intel_Atom_Saltwell, /**< 32nm shrink of Bonnell. */ + kCpumMicroarch_Intel_Atom_Silvermont, /**< 22nm */ + kCpumMicroarch_Intel_Atom_Airmount, /**< 14nm */ + kCpumMicroarch_Intel_Atom_Goldmont, /**< 14nm */ + kCpumMicroarch_Intel_Atom_Unknown, + kCpumMicroarch_Intel_Atom_End, + + kCpumMicroarch_Intel_P6_Core_Atom_End, + + kCpumMicroarch_Intel_NB_First, + kCpumMicroarch_Intel_NB_Willamette = kCpumMicroarch_Intel_NB_First, /**< 180nm */ + kCpumMicroarch_Intel_NB_Northwood, /**< 130nm */ + kCpumMicroarch_Intel_NB_Prescott, /**< 90nm */ + kCpumMicroarch_Intel_NB_Prescott2M, /**< 90nm */ + kCpumMicroarch_Intel_NB_CedarMill, /**< 65nm */ + kCpumMicroarch_Intel_NB_Gallatin, /**< 90nm Xeon, Pentium 4 Extreme Edition ("Emergency Edition"). */ + kCpumMicroarch_Intel_NB_Unknown, + kCpumMicroarch_Intel_NB_End, + + kCpumMicroarch_Intel_Unknown, + kCpumMicroarch_Intel_End, + + kCpumMicroarch_AMD_First, + kCpumMicroarch_AMD_Am286 = kCpumMicroarch_AMD_First, + kCpumMicroarch_AMD_Am386, + kCpumMicroarch_AMD_Am486, + kCpumMicroarch_AMD_Am486Enh, /**< Covers Am5x86 as well. */ + kCpumMicroarch_AMD_K5, + kCpumMicroarch_AMD_K6, + + kCpumMicroarch_AMD_K7_First, + kCpumMicroarch_AMD_K7_Palomino = kCpumMicroarch_AMD_K7_First, + kCpumMicroarch_AMD_K7_Spitfire, + kCpumMicroarch_AMD_K7_Thunderbird, + kCpumMicroarch_AMD_K7_Morgan, + kCpumMicroarch_AMD_K7_Thoroughbred, + kCpumMicroarch_AMD_K7_Barton, + kCpumMicroarch_AMD_K7_Unknown, + kCpumMicroarch_AMD_K7_End, + + kCpumMicroarch_AMD_K8_First, + kCpumMicroarch_AMD_K8_130nm = kCpumMicroarch_AMD_K8_First, /**< 130nm Clawhammer, Sledgehammer, Newcastle, Paris, Odessa, Dublin */ + kCpumMicroarch_AMD_K8_90nm, /**< 90nm shrink */ + kCpumMicroarch_AMD_K8_90nm_DualCore, /**< 90nm with two cores. */ + kCpumMicroarch_AMD_K8_90nm_AMDV, /**< 90nm with AMD-V (usually) and two cores (usually). */ + kCpumMicroarch_AMD_K8_65nm, /**< 65nm shrink. */ + kCpumMicroarch_AMD_K8_End, + + kCpumMicroarch_AMD_K10, + kCpumMicroarch_AMD_K10_Lion, + kCpumMicroarch_AMD_K10_Llano, + kCpumMicroarch_AMD_Bobcat, + kCpumMicroarch_AMD_Jaguar, + + kCpumMicroarch_AMD_15h_First, + kCpumMicroarch_AMD_15h_Bulldozer = kCpumMicroarch_AMD_15h_First, + kCpumMicroarch_AMD_15h_Piledriver, + kCpumMicroarch_AMD_15h_Steamroller, /**< Yet to be released, might have different family. */ + kCpumMicroarch_AMD_15h_Excavator, /**< Yet to be released, might have different family. */ + kCpumMicroarch_AMD_15h_Unknown, + kCpumMicroarch_AMD_15h_End, + + kCpumMicroarch_AMD_16h_First, + kCpumMicroarch_AMD_16h_End, + + kCpumMicroarch_AMD_Unknown, + kCpumMicroarch_AMD_End, + + kCpumMicroarch_VIA_First, + kCpumMicroarch_Centaur_C6 = kCpumMicroarch_VIA_First, + kCpumMicroarch_Centaur_C2, + kCpumMicroarch_Centaur_C3, + kCpumMicroarch_VIA_C3_M2, + kCpumMicroarch_VIA_C3_C5A, /**< 180nm Samuel - Cyrix III, C3, 1GigaPro. */ + kCpumMicroarch_VIA_C3_C5B, /**< 150nm Samuel 2 - Cyrix III, C3, 1GigaPro, Eden ESP, XP 2000+. */ + kCpumMicroarch_VIA_C3_C5C, /**< 130nm Ezra - C3, Eden ESP. */ + kCpumMicroarch_VIA_C3_C5N, /**< 130nm Ezra-T - C3. */ + kCpumMicroarch_VIA_C3_C5XL, /**< 130nm Nehemiah - C3, Eden ESP, Eden-N. */ + kCpumMicroarch_VIA_C3_C5P, /**< 130nm Nehemiah+ - C3. */ + kCpumMicroarch_VIA_C7_C5J, /**< 90nm Esther - C7, C7-D, C7-M, Eden, Eden ULV. */ + kCpumMicroarch_VIA_Isaiah, + kCpumMicroarch_VIA_Unknown, + kCpumMicroarch_VIA_End, + + kCpumMicroarch_Cyrix_First, + kCpumMicroarch_Cyrix_5x86 = kCpumMicroarch_Cyrix_First, + kCpumMicroarch_Cyrix_M1, + kCpumMicroarch_Cyrix_MediaGX, + kCpumMicroarch_Cyrix_MediaGXm, + kCpumMicroarch_Cyrix_M2, + kCpumMicroarch_Cyrix_Unknown, + kCpumMicroarch_Cyrix_End, + + kCpumMicroarch_Unknown, + + kCpumMicroarch_32BitHack = 0x7fffffff +} CPUMMICROARCH; + + +/** Predicate macro for catching netburst CPUs. */ +#define CPUMMICROARCH_IS_INTEL_NETBURST(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_Intel_NB_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_NB_End) + +/** Predicate macro for catching Core7 CPUs. */ +#define CPUMMICROARCH_IS_INTEL_CORE7(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_Intel_Core7_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_Core7_End) + +/** Predicate macro for catching AMD Family OFh CPUs (aka K8). */ +#define CPUMMICROARCH_IS_AMD_FAM_0FH(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_AMD_K8_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_K8_End) + +/** Predicate macro for catching AMD Family 10H CPUs (aka K10). */ +#define CPUMMICROARCH_IS_AMD_FAM_10H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10) + +/** Predicate macro for catching AMD Family 11H CPUs (aka Lion). */ +#define CPUMMICROARCH_IS_AMD_FAM_11H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Lion) + +/** Predicate macro for catching AMD Family 12H CPUs (aka Llano). */ +#define CPUMMICROARCH_IS_AMD_FAM_12H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Llano) + +/** Predicate macro for catching AMD Family 14H CPUs (aka Bobcat). */ +#define CPUMMICROARCH_IS_AMD_FAM_14H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_Bobcat) + +/** Predicate macro for catching AMD Family 15H CPUs (bulldozer and it's + * decendants). */ +#define CPUMMICROARCH_IS_AMD_FAM_15H(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_AMD_15h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_15h_End) + +/** Predicate macro for catching AMD Family 16H CPUs. */ +#define CPUMMICROARCH_IS_AMD_FAM_16H(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_AMD_16h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_16h_End) + + + +/** + * CPUID leaf. + */ +typedef struct CPUMCPUIDLEAF +{ + /** The leaf number. */ + uint32_t uLeaf; + /** The sub-leaf number. */ + uint32_t uSubLeaf; + /** Sub-leaf mask. This is 0 when sub-leaves aren't used. */ + uint32_t fSubLeafMask; + + /** The EAX value. */ + uint32_t uEax; + /** The EBX value. */ + uint32_t uEbx; + /** The ECX value. */ + uint32_t uEcx; + /** The EDX value. */ + uint32_t uEdx; + + /** Flags. */ + uint32_t fFlags; +} CPUMCPUIDLEAF; +/** Pointer to a CPUID leaf. */ +typedef CPUMCPUIDLEAF *PCPUMCPUIDLEAF; +/** Pointer to a const CPUID leaf. */ +typedef CPUMCPUIDLEAF const *PCCPUMCPUIDLEAF; + +/** @name CPUMCPUIDLEAF::fFlags + * @{ */ +/** Indicates that ECX (the sub-leaf indicator) doesn't change when + * requesting the final leaf and all undefined leaves that follows it. + * Observed for 0x0000000b on Intel. */ +#define CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED RT_BIT_32(0) +/** @} */ + +/** + * Method used to deal with unknown CPUID leafs. + */ +typedef enum CPUMUKNOWNCPUID +{ + /** Invalid zero value. */ + CPUMUKNOWNCPUID_INVALID = 0, + /** Use given default values (DefCpuId). */ + CPUMUKNOWNCPUID_DEFAULTS, + /** Return the last standard leaf. + * Intel Sandy Bridge has been observed doing this. */ + CPUMUKNOWNCPUID_LAST_STD_LEAF, + /** Return the last standard leaf, with ecx observed. + * Intel Sandy Bridge has been observed doing this. */ + CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX, + /** The register values are passed thru unmodified. */ + CPUMUKNOWNCPUID_PASSTHRU, + /** End of valid value. */ + CPUMUKNOWNCPUID_END, + /** Ensure 32-bit type. */ + CPUMUKNOWNCPUID_32BIT_HACK = 0x7fffffff +} CPUMUKNOWNCPUID; +/** Pointer to unknown CPUID leaf method. */ +typedef CPUMUKNOWNCPUID *PCPUMUKNOWNCPUID; + + + /** @name Guest Register Getters. * @{ */ VMMDECL(void) CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR); @@ -172,6 +418,8 @@ VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeatur VMMDECL(void) CPUMSetGuestCtx(PVMCPU pVCpu, const PCPUMCTX pCtx); VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenCsAndSs(PVMCPU pVCpu); VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg); +VMMR0_INT_DECL(void) CPUMR0SetGuestTscAux(PVMCPU pVCpu, uint64_t uValue); +VMMR0_INT_DECL(uint64_t) CPUMR0GetGuestTscAux(PVMCPU pVCpu); /** @} */ @@ -215,7 +463,18 @@ DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCPUMCTX pCtx) DECLINLINE(bool) CPUMIsGuestInRealOrV86ModeEx(PCPUMCTX pCtx) { return !(pCtx->cr0 & X86_CR0_PE) - || pCtx->eflags.Bits.u1VM; /** @todo verify that this cannot be set in long mode. */ + || pCtx->eflags.Bits.u1VM; /* Cannot be set in long mode. Intel spec 2.3.1 "System Flags and Fields in IA-32e Mode". */ +} + +/** + * Tests if the guest is running in virtual 8086 mode. + * + * @returns @c true if it is, @c false if not. + * @param pCtx Current CPU context + */ +DECLINLINE(bool) CPUMIsGuestInV86ModeEx(PCPUMCTX pCtx) +{ + return (pCtx->eflags.Bits.u1VM == 1); } /** @@ -258,6 +517,17 @@ DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx) return pCtx->cs.Attr.n.u1Long; } +/** + * Tests if the guest has paging enabled or not. + * + * @returns true if paging is enabled, otherwise false. + * @param pCtx Current CPU context + */ +DECLINLINE(bool) CPUMIsGuestPagingEnabledEx(PCPUMCTX pCtx) +{ + return !!(pCtx->cr0 & X86_CR0_PG); +} + /** * Tests if the guest is running in PAE mode or not. * @@ -266,9 +536,11 @@ DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx) */ DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCPUMCTX pCtx) { - return ( (pCtx->cr4 & X86_CR4_PAE) - && CPUMIsGuestInPagedProtectedModeEx(pCtx) - && !CPUMIsGuestInLongModeEx(pCtx)); + /* Intel mentions EFER.LMA and EFER.LME in different parts of their spec. We shall use EFER.LMA rather + than EFER.LME as it reflects if the CPU has entered paging with EFER.LME set. */ + return ( (pCtx->cr4 & X86_CR4_PAE) + && CPUMIsGuestPagingEnabledEx(pCtx) + && !(pCtx->msrEFER & MSR_K6_EFER_LMA)); } #endif /* VBOX_WITHOUT_UNNAMED_UNIONS */ @@ -341,7 +613,7 @@ VMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3); VMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6); VMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7); VMMDECL(void) CPUMSetHyperCtx(PVMCPU pVCpu, const PCPUMCTX pCtx); -VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu); +VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu, uint8_t iGstReg, bool fForceHyper); /** @} */ VMMDECL(void) CPUMPushHyper(PVMCPU pVCpu, uint32_t u32); @@ -350,11 +622,10 @@ VMMDECL(PCPUMCTX) CPUMGetHyperCtxPtr(PVMCPU pVCpu); VMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu); VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu); VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu); -VMMR3DECL(int) CPUMR3RawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); -VMMR3DECL(int) CPUMR3RawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc); +VMM_INT_DECL(int) CPUMRawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); +VMM_INT_DECL(int) CPUMRawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc); VMMDECL(uint32_t) CPUMRawGetEFlags(PVMCPU pVCpu); VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl); -VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu); /** @name Changed flags. * These flags are used to keep track of which important register that @@ -394,16 +665,32 @@ VMMR3DECL(void) CPUMR3RemLeave(PVMCPU pVCpu, bool fNoOutOfSyncSels); VMMDECL(bool) CPUMSupportsFXSR(PVM pVM); VMMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM); VMMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM); -VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCPU); +VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCpu); VMMDECL(void) CPUMDeactivateGuestFPUState(PVMCPU pVCpu); VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu); +VMMDECL(bool) CPUMIsGuestDebugStateActivePending(PVMCPU pVCpu); VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu); VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu); -VMMDECL(void) CPUMDeactivateHyperDebugState(PVMCPU pVCpu); +VMMDECL(bool) CPUMIsHyperDebugStateActivePending(PVMCPU pVCpu); VMMDECL(uint32_t) CPUMGetGuestCPL(PVMCPU pVCpu); VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu); VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu); VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu); +VMMDECL(uint64_t) CPUMGetGuestScalableBusFrequency(PVM pVM); + +/** @name Typical scalable bus frequency values. + * @{ */ +/** Special internal value indicating that we don't know the frequency. + * @internal */ +#define CPUM_SBUSFREQ_UNKNOWN UINT64_C(1) +#define CPUM_SBUSFREQ_100MHZ UINT64_C(100000000) +#define CPUM_SBUSFREQ_133MHZ UINT64_C(133333333) +#define CPUM_SBUSFREQ_167MHZ UINT64_C(166666666) +#define CPUM_SBUSFREQ_200MHZ UINT64_C(200000000) +#define CPUM_SBUSFREQ_267MHZ UINT64_C(266666666) +#define CPUM_SBUSFREQ_333MHZ UINT64_C(333333333) +#define CPUM_SBUSFREQ_400MHZ UINT64_C(400000000) +/** @} */ #ifdef IN_RING3 @@ -413,10 +700,12 @@ VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu); */ VMMR3DECL(int) CPUMR3Init(PVM pVM); +VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM); +VMMR3DECL(void) CPUMR3LogCpuIds(PVM pVM); VMMR3DECL(void) CPUMR3Relocate(PVM pVM); VMMR3DECL(int) CPUMR3Term(PVM pVM); VMMR3DECL(void) CPUMR3Reset(PVM pVM); -VMMR3DECL(void) CPUMR3ResetCpu(PVMCPU pVCpu); +VMMR3DECL(void) CPUMR3ResetCpu(PVM pVM, PVMCPU pVCpu); VMMDECL(bool) CPUMR3IsStateRestorePending(PVM pVM); VMMR3DECL(void) CPUMR3SetHWVirtEx(PVM pVM, bool fHWVirtExEnabled); VMMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd); @@ -425,6 +714,15 @@ VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdExtRCPtr(PVM pVM); VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdCentaurRCPtr(PVM pVM); VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdDefRCPtr(PVM pVM); +VMMR3DECL(CPUMMICROARCH) CPUMR3CpuIdDetermineMicroarchEx(CPUMCPUVENDOR enmVendor, uint8_t bFamily, + uint8_t bModel, uint8_t bStepping); +VMMR3DECL(const char *) CPUMR3MicroarchName(CPUMMICROARCH enmMicroarch); +VMMR3DECL(int) CPUMR3CpuIdCollectLeaves(PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves); +VMMR3DECL(int) CPUMR3CpuIdDetectUnknownLeafMethod(PCPUMUKNOWNCPUID penmUnknownMethod, PCPUMCPUID pDefUnknown); +VMMR3DECL(const char *) CPUMR3CpuIdUnknownLeafMethodName(CPUMUKNOWNCPUID enmUnknownMethod); +VMMR3DECL(CPUMCPUVENDOR) CPUMR3CpuIdDetectVendorEx(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX); +VMMR3DECL(const char *) CPUMR3CpuVendorName(CPUMCPUVENDOR enmVendor); + /** @} */ #endif /* IN_RING3 */ @@ -459,6 +757,12 @@ DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint3 */ DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame); +VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu); +VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +#ifdef VBOX_WITH_RAW_RING1 +VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); +#endif + /** @} */ #endif /* IN_RC */ @@ -467,18 +771,20 @@ DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame); * @ingroup grp_cpum * @{ */ -VMMR0DECL(int) CPUMR0ModuleInit(void); -VMMR0DECL(int) CPUMR0ModuleTerm(void); -VMMR0DECL(int) CPUMR0Init(PVM pVM); -VMMR0DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) CPUMR0SaveGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6); -VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6); -VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6); +VMMR0_INT_DECL(int) CPUMR0ModuleInit(void); +VMMR0_INT_DECL(int) CPUMR0ModuleTerm(void); +VMMR0_INT_DECL(int) CPUMR0InitVM(PVM pVM); +VMMR0_INT_DECL(int) CPUMR0Trap07Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuestAndRestoreHost(PVMCPU pVCpu, bool fDr6); +VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuest(PVMCPU pVCpu, bool fDr6); + +VMMR0_INT_DECL(void) CPUMR0LoadGuestDebugState(PVMCPU pVCpu, bool fDr6); +VMMR0_INT_DECL(void) CPUMR0LoadHyperDebugState(PVMCPU pVCpu, bool fDr6); #ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI -VMMR0DECL(void) CPUMR0SetLApic(PVM pVM, RTCPUID idHostCpu); +VMMR0_INT_DECL(void) CPUMR0SetLApic(PVMCPU pVCpu, RTCPUID idHostCpu); #endif /** @} */ diff --git a/include/VBox/vmm/cpum.mac b/include/VBox/vmm/cpum.mac index 8f906d06..48d3eb70 100644 --- a/include/VBox/vmm/cpum.mac +++ b/include/VBox/vmm/cpum.mac @@ -3,7 +3,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; @@ -193,7 +193,8 @@ struc CPUMCTX .msrCSTAR resb 8 .msrSFMASK resb 8 .msrKERNELGSBASE resb 8 - .au32SizePadding resb 32 + .msrApicBase resb 8 + .au32SizePadding resb 24 endstruc @@ -205,3 +206,4 @@ endstruc %endif + diff --git a/include/VBox/vmm/cpumctx.h b/include/VBox/vmm/cpumctx.h index 35861823..c4c9df3b 100644 --- a/include/VBox/vmm/cpumctx.h +++ b/include/VBox/vmm/cpumctx.h @@ -135,7 +135,8 @@ typedef struct CPUMSYSENTER /** * CPU context core. * - * @todo eliminate this structure! + * @todo Eliminate this structure! + * @deprecated We don't push any context cores any more in TRPM. */ #pragma pack(1) typedef struct CPUMCTXCORE @@ -399,10 +400,11 @@ typedef struct CPUMCTX uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */ uint64_t msrSFMASK; /**< syscall flag mask. */ uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */ + uint64_t msrApicBase; /**< The local APIC base (IA32_APIC_BASE MSR). */ /** @} */ /** Size padding. */ - uint32_t au32SizePadding[8]; + uint32_t au32SizePadding[6]; } CPUMCTX; #pragma pack() @@ -413,6 +415,11 @@ typedef struct CPUMCTX */ # define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax) +/** + * Gets the CPUMCTXCORE part of a CPUMCTX. + */ +# define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax) + /** * Gets the first selector register of a CPUMCTX. * @@ -446,6 +453,7 @@ typedef union CPUMCTXMSRS uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */ uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */ uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */ + uint64_t PkgCStateCfgCtrl; /**< MSR_PKG_CST_CONFIG_CONTROL */ } msr; uint64_t au64[64]; } CPUMCTXMSRS; diff --git a/include/VBox/vmm/cpumdis.h b/include/VBox/vmm/cpumdis.h index 9aa509a3..dab556a8 100644 --- a/include/VBox/vmm/cpumdis.h +++ b/include/VBox/vmm/cpumdis.h @@ -3,7 +3,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/include/VBox/vmm/csam.h b/include/VBox/vmm/csam.h index 675cac7f..99a68563 100644 --- a/include/VBox/vmm/csam.h +++ b/include/VBox/vmm/csam.h @@ -3,7 +3,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; @@ -28,13 +28,14 @@ #include +#if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING) /** @defgroup grp_csam The Code Scanning and Analysis API * @{ */ /** - * CSAM monitoring tag + * CSAM monitoring tag. * For use with CSAMR3MonitorPage */ typedef enum CSAMTAG @@ -50,99 +51,23 @@ typedef enum CSAMTAG RT_C_DECLS_BEGIN -/** - * Check if this page needs to be analysed by CSAM. - * - * This function should only be called for supervisor pages and - * only when CSAM is enabled. Leaving these selection criteria - * to the caller simplifies the interface (PTE passing). - * - * Note the the page has not yet been synced, so the TLB trick - * (which wasn't ever active anyway) cannot be applied. - * - * @returns true if the page should be marked not present because - * CSAM want need to scan it. - * @returns false if the page was already scanned. - * @param pVM The VM to operate on. - * @param GCPtr GC pointer of page table entry - */ -VMMDECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr); - -/** - * Check if this page was previously scanned by CSAM - * - * @returns true -> scanned, false -> not scanned - * @param pVM The VM to operate on. - * @param pPage GC page address - */ -VMMDECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage); - -/** - * Mark a page as scanned/not scanned - * - * @note: we always mark it as scanned, even if we haven't completely done so - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pPage GC page address (not necessarily aligned) - * @param fScanned Mark as scanned or not scanned - * - */ -VMMDECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned); - - -/** - * Remember a possible code page for later inspection - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param GCPtr GC pointer of page - */ -VMMDECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr); - /** * Query CSAM state (enabled/disabled) * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -#define CSAMIsEnabled(pVM) (pVM->fCSAMEnabled && EMIsRawRing0Enabled(pVM)) - -/** - * Turn on code scanning - * - * @returns VBox status code. (trap handled or not) - * @param pVM The VM to operate on. + * @returns true / false. + * @param a_pVM The shared VM handle. + * @internal */ -VMMDECL(int) CSAMEnableScanning(PVM pVM); - -/** - * Turn off code scanning - * - * @returns VBox status code. (trap handled or not) - * @param pVM The VM to operate on. - */ -VMMDECL(int) CSAMDisableScanning(PVM pVM); +#define CSAMIsEnabled(a_pVM) ((a_pVM)->fCSAMEnabled && EMIsRawRing0Enabled(a_pVM)) - -/** - * Check if this page needs to be analysed by CSAM - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - * @param pvFault Fault address - */ -VMMDECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault); - -/** - * Check if we've scanned this instruction before. If true, then we can emulate - * it instead of returning to ring 3. - * - * @returns boolean - * @param pVM The VM to operate on. - * @param GCPtr GC pointer of page table entry - */ -VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr); +VMM_INT_DECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr); +VMM_INT_DECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage); +VMM_INT_DECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned); +VMM_INT_DECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr); +VMM_INT_DECL(int) CSAMEnableScanning(PVM pVM); +VMM_INT_DECL(int) CSAMDisableScanning(PVM pVM); +VMM_INT_DECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault); +VMM_INT_DECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr); #ifdef IN_RING3 @@ -151,149 +76,25 @@ VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr); * @{ */ -/** - * Query CSAM state (enabled/disabled) - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) CSAMR3IsEnabled(PVM pVM); +VMMR3DECL(bool) CSAMR3IsEnabled(PUVM pUVM); +VMMR3DECL(int) CSAMR3SetScanningEnabled(PUVM pUVM, bool fEnabled); -/** - * Initializes the csam. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) CSAMR3Init(PVM pVM); +VMMR3_INT_DECL(int) CSAMR3Init(PVM pVM); +VMMR3_INT_DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) CSAMR3Term(PVM pVM); +VMMR3_INT_DECL(int) CSAMR3Reset(PVM pVM); -/** - * Applies relocations to data and code managed by this - * component. This function will be called at init and - * whenever the VMM need to relocate it self inside the GC. - * - * The csam will update the addresses used by the switcher. - * - * @param pVM The VM. - * @param offDelta Relocation delta. - */ -VMMR3DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta); - -/** - * Terminates the csam. - * - * Termination means cleaning up and freeing all resources, - * the VM it self is at this point powered off or suspended. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) CSAMR3Term(PVM pVM); - -/** - * CSAM reset callback. - * - * @returns VBox status code. - * @param pVM The VM which is reset. - */ -VMMR3DECL(int) CSAMR3Reset(PVM pVM); +VMMR3_INT_DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr); +VMMR3_INT_DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr); +VMMR3_INT_DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned); +VMMR3_INT_DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates); - -/** - * Notify CSAM of a page flush - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param addr GC address of the page to flush - */ -VMMR3DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr); - -/** - * Remove a CSAM monitored page. Use with care! - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param addr GC address of the page to flush - */ -VMMR3DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr); - -/** - * Scan and analyse code - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pCtxCore CPU context - * @param pInstrGC Instruction pointer - */ -VMMR3DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC); - -/** - * Scan and analyse code - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstrGC Instruction pointer (0:32 virtual address) - */ -VMMR3DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC); - -/** - * Mark an instruction in a page as scanned/not scanned - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Instruction pointer - * @param cbInstr Instruction size - * @param fScanned Mark as scanned or not - */ -VMMR3DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned); - -/** - * Perform any pending actions - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pVCpu The VMCPU to operate on. - */ -VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu); - -/** - * Monitors a code page (if not already monitored) - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param pPageAddrGC The page to monitor - * @param enmTag Monitor tag - */ -VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); - -/** - * Unmonitors a code page - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param pPageAddrGC The page to monitor - * @param enmTag Monitor tag - */ -VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); - -/** - * Analyse interrupt and trap gates - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param iGate Start gate - * @param cGates Number of gates to check - */ -VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates); - -/** - * Record previous call instruction addresses - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param GCPtrCall Call address - */ -VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall); +VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); +VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); +VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall); /** @} */ #endif @@ -302,4 +103,7 @@ VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall); /** @} */ RT_C_DECLS_END +#endif /* VBOX_WITH_RAW_MODE */ + #endif + diff --git a/include/VBox/vmm/dbgf.h b/include/VBox/vmm/dbgf.h index 65bb94c7..9aa4be5b 100644 --- a/include/VBox/vmm/dbgf.h +++ b/include/VBox/vmm/dbgf.h @@ -3,7 +3,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; @@ -46,8 +46,8 @@ RT_C_DECLS_BEGIN * @ingroup grp_dbgf * @{ */ -VMMRZDECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6); -VMMRZDECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMMRZ_INT_DECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6, bool fAltStepping); +VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); /** @} */ #endif @@ -114,14 +114,14 @@ typedef const DBGFADDRESS *PCDBGFADDRESS; #define DBGFADDRESS_IS_HMA(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) ) /** @} */ -VMMR3DECL(int) DBGFR3AddrFromSelOff(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off); -VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PVM pVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off); -VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr); -VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr); -VMMR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress); -VMMR3DECL(int) DBGFR3AddrToPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys); -VMMR3DECL(int) DBGFR3AddrToHostPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys); -VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr); +VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off); +VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PUVM pUVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off); +VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PUVM pUVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr); +VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr); +VMMR3DECL(bool) DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress); +VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys); +VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys); +VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr); VMMR3DECL(PDBGFADDRESS) DBGFR3AddrAdd(PDBGFADDRESS pAddress, RTGCUINTPTR uAddend); VMMR3DECL(PDBGFADDRESS) DBGFR3AddrSub(PDBGFADDRESS pAddress, RTGCUINTPTR uSubtrahend); @@ -179,10 +179,10 @@ typedef enum DBGFEVENTTYPE * to bring up the debugger at a specific place. */ DBGFEVENT_DEV_STOP, - /** The VM is terminating. + /** The VM is powering off. * When this notification is received, the debugger thread should detach ASAP. */ - DBGFEVENT_TERMINATING, + DBGFEVENT_POWERING_OFF, /** The usual 32-bit hack. */ DBGFEVENT_32BIT_HACK = 0x7fffffff @@ -201,7 +201,7 @@ typedef enum DBGFEVENTCTX /** Recompiled mode. */ DBGFEVENTCTX_REM, /** VMX / AVT mode. */ - DBGFEVENTCTX_HWACCL, + DBGFEVENTCTX_HM, /** Hypervisor context. */ DBGFEVENTCTX_HYPER, /** Other mode */ @@ -281,24 +281,29 @@ typedef const DBGFEVENT *PCDBGFEVENT; # define DBGFSTOP(pVM) VINF_SUCCESS # endif -VMMR3DECL(int) DBGFR3Init(PVM pVM); -VMMR3DECL(int) DBGFR3Term(PVM pVM); -VMMR3DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(int) DBGFR3VMMForcedAction(PVM pVM); -VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent); -VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, ...); -VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, va_list args); -VMMR3DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2); -VMMR3DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent); -VMMR3DECL(int) DBGFR3Attach(PVM pVM); -VMMR3DECL(int) DBGFR3Detach(PVM pVM); -VMMR3DECL(int) DBGFR3EventWait(PVM pVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent); -VMMR3DECL(int) DBGFR3Halt(PVM pVM); -VMMR3DECL(bool) DBGFR3IsHalted(PVM pVM); -VMMR3DECL(bool) DBGFR3CanWait(PVM pVM); -VMMR3DECL(int) DBGFR3Resume(PVM pVM); -VMMR3DECL(int) DBGFR3Step(PVM pVM, VMCPUID idCpu); -VMMR3DECL(int) DBGFR3PrgStep(PVMCPU pVCpu); +VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM); +VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM); +VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM); +VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM); +VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent); +VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, + const char *pszFunction, const char *pszFormat, ...); +VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, + const char *pszFunction, const char *pszFormat, va_list args); +VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2); +VMMR3_INT_DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent); +VMMR3_INT_DECL(int) DBGFR3PrgStep(PVMCPU pVCpu); + +VMMR3DECL(int) DBGFR3Attach(PUVM pUVM); +VMMR3DECL(int) DBGFR3Detach(PUVM pUVM); +VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent); +VMMR3DECL(int) DBGFR3Halt(PUVM pUVM); +VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM); +VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM); +VMMR3DECL(int) DBGFR3Resume(PUVM pUVM); +VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(int) DBGFR3InjectNMI(PUVM pUVM, VMCPUID idCpu); #endif /* IN_RING3 */ @@ -384,39 +389,44 @@ typedef DBGFBP *PDBGFBP; typedef const DBGFBP *PCDBGFBP; #ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */ -VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); -VMMR3DECL(int) DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, +VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); +VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint8_t fType, uint8_t cb, uint32_t *piBp); -VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); -VMMR3DECL(int) DBGFR3BpClear(PVM pVM, uint32_t iBp); -VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, uint32_t iBp); -VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, uint32_t iBp); +VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); +VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, uint32_t iBp); +VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, uint32_t iBp); +VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, uint32_t iBp); /** * Breakpoint enumeration callback function. * * @returns VBox status code. Any failure will stop the enumeration. - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param pvUser The user argument. * @param pBp Pointer to the breakpoint information. (readonly) */ -typedef DECLCALLBACK(int) FNDBGFBPENUM(PVM pVM, void *pvUser, PCDBGFBP pBp); +typedef DECLCALLBACK(int) FNDBGFBPENUM(PUVM pUVM, void *pvUser, PCDBGFBP pBp); /** Pointer to a breakpoint enumeration callback function. */ typedef FNDBGFBPENUM *PFNDBGFBPENUM; -VMMR3DECL(int) DBGFR3BpEnum(PVM pVM, PFNDBGFBPENUM pfnCallback, void *pvUser); +VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser); #endif /* IN_RING3 */ -VMMDECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM); -VMMDECL(bool) DBGFIsStepping(PVMCPU pVCpu); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM); +VMM_INT_DECL(bool) DBGFBpIsHwArmed(PVM pVM); +VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM); +VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu); +VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue); #ifdef IN_RING3 /* The CPU mode API only works in ring-3. */ -VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PVM pVM, VMCPUID idCpu); +VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM); +VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu); #endif @@ -510,37 +520,37 @@ typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT; #define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0) /** @} */ -VMMR3DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns); -VMMR3DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns); -VMMR3DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler); -VMMR3DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags); -VMMR3DECL(int) DBGFR3InfoRegisterExternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser); -VMMR3DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName); -VMMR3DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName); -VMMR3DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName); -VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PVM pVM, const char *pszName); -VMMR3DECL(int) DBGFR3Info(PVM pVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); -VMMR3DECL(int) DBGFR3InfoEx(PVM pVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); -VMMR3DECL(int) DBGFR3InfoLogRel(PVM pVM, const char *pszName, const char *pszArgs); -VMMR3DECL(int) DBGFR3InfoStdErr(PVM pVM, const char *pszName, const char *pszArgs); -VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat, - const char *pszSepFmt, PCDBGFINFOHLP pHlp); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags); +VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser); +VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName); +VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName); +VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName); +VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName); +VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); +VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); +VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs); +VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs); +VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat, + const char *pszSepFmt, PCDBGFINFOHLP pHlp); /** @def DBGFR3InfoLog * Display a piece of info writing to the log if enabled. * - * @param pVM VM handle. - * @param pszName The identifier of the info to display. - * @param pszArgs Arguments to the info handler. + * @param a_pVM The shared VM handle. + * @param a_pszName The identifier of the info to display. + * @param a_pszArgs Arguments to the info handler. */ #ifdef LOG_ENABLED -#define DBGFR3InfoLog(pVM, pszName, pszArgs) \ +# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) \ do { \ if (LogIsEnabled()) \ - DBGFR3Info(pVM, pszName, pszArgs, NULL); \ + DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \ } while (0) #else -#define DBGFR3InfoLog(pVM, pszName, pszArgs) do { } while (0) +# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) do { } while (0) #endif /** @@ -549,15 +559,15 @@ VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *p * @returns VBox status code. * A status code indicating failure will end the enumeration * and DBGFR3InfoEnum will return with that status code. - * @param pVM VM handle. + * @param pUVM The user mode VM handle. * @param pszName Info identifier name. * @param pszDesc The description. */ -typedef DECLCALLBACK(int) FNDBGFINFOENUM(PVM pVM, const char *pszName, const char *pszDesc, void *pvUser); +typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser); /** Pointer to a FNDBGFINFOENUM function. */ typedef FNDBGFINFOENUM *PFNDBGFINFOENUM; -VMMR3DECL(int) DBGFR3InfoEnum(PVM pVM, PFNDBGFINFOENUM pfnCallback, void *pvUser); +VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser); VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void); VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void); @@ -565,9 +575,9 @@ VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void); #ifdef IN_RING3 /* The log contrl API only works in ring-3. */ -VMMR3DECL(int) DBGFR3LogModifyGroups(PVM pVM, const char *pszGroupSettings); -VMMR3DECL(int) DBGFR3LogModifyFlags(PVM pVM, const char *pszFlagSettings); -VMMR3DECL(int) DBGFR3LogModifyDestinations(PVM pVM, const char *pszDestSettings); +VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings); +VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings); +VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings); #endif /* IN_RING3 */ #ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */ @@ -650,33 +660,32 @@ typedef const DBGFLINE *PCDBGFLINE; /** @} */ -VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId); -VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs); -VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor); -VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PVM pVM, RTDBGAS hAlias); -VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias); -VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName); -VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId); - -VMMR3DECL(int) DBGFR3AsLoadImage(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); -VMMR3DECL(int) DBGFR3AsLoadMap(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags); -VMMR3DECL(int) DBGFR3AsLinkModule(PVM pVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); - -VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); -VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod); -VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); - -/* The following are soon to be obsoleted: */ -VMMR3DECL(int) DBGFR3ModuleLoad(PVM pVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage); -VMMR3DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage, - const char *pszFilename, const char *pszName); -VMMR3DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol); -VMMR3DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol); -VMMR3DECL(int) DBGFR3SymbolByName(PVM pVM, const char *pszSymbol, PDBGFSYMBOL pSymbol); - -VMMR3DECL(int) DBGFR3LineByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine); -VMMR3DECL(PDBGFLINE) DBGFR3LineByAddrAlloc(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement); -VMMR3DECL(void) DBGFR3LineFree(PDBGFLINE pLine); +VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM); + +VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId); +VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs); +VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor); +VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias); +VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias); +VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName); +VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId); + +VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, + RTLDRARCH enmArch, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); +VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags); +VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); +VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName); + +VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags, + PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); +VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags, + PRTGCINTPTR poffDisp, PRTDBGMOD phMod); +VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); + +VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, + PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod); +VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, + PRTGCINTPTR poffDisp, PRTDBGMOD phMod); #endif /* IN_RING3 */ @@ -769,7 +778,7 @@ typedef struct DBGFSTACKFRAME /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */ PRTDBGSYMBOL pSymPC; /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */ - PDBGFLINE pLinePC; + PRTDBGLINE pLinePC; /** The return frame address. * The off member is [e|r]bp and the Sel member is ss. */ @@ -786,7 +795,7 @@ typedef struct DBGFSTACKFRAME /** Pointer to the symbol nearest the return PC. NULL if not found. */ PRTDBGSYMBOL pSymReturnPC; /** Pointer to the linnumber nearest the return PC. NULL if not found. */ - PDBGFLINE pLineReturnPC; + PRTDBGLINE pLineReturnPC; /** 32-bytes of stack arguments. */ union @@ -846,8 +855,9 @@ typedef enum DBGFCODETYPE } DBGFCODETYPE; /** @} */ -VMMR3DECL(int) DBGFR3StackWalkBegin(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame); -VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, +VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, + PCDBGFSTACKFRAME *ppFirstFrame); +VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC, DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame); VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent); @@ -872,6 +882,12 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame); #define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4) /** No address in the output. */ #define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5) +/** Probably a hypervisor instruction. */ +#define DBGF_DISAS_FLAGS_HYPER RT_BIT(6) +/** Disassemble original unpatched bytes (PATM). */ +#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7) +/** Annotate patched instructions. */ +#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8) /** Disassemble in the default mode of the specific context. */ #define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000) /** Disassemble in 16-bit mode. */ @@ -885,29 +901,29 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame); /** The disassembly mode mask. */ #define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000) /** Mask containing the valid flags. */ -#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x7000007f) +#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff) /** @} */ /** Special flat selector. */ #define DBGF_SEL_FLAT 1 -VMMR3DECL(int) DBGFR3DisasInstrEx(PVM pVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags, - char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr); -VMMR3DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput); -VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix); +VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags, + char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr); +VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput); +VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix); /** @def DBGFR3DisasInstrCurrentLog * Disassembles the current guest context instruction and writes it to the log. * All registers and data will be displayed. Addresses will be attempted resolved to symbols. */ #ifdef LOG_ENABLED -# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) \ +# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \ do { \ if (LogIsEnabled()) \ DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \ } while (0) #else -# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) do { } while (0) +# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0) #endif VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix); @@ -918,23 +934,23 @@ VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPt * @thread Any EMT. */ # ifdef LOG_ENABLED -# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) \ +# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \ do { \ if (LogIsEnabled()) \ DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \ } while (0) # else -# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0) +# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0) # endif #endif #ifdef IN_RING3 -VMMR3DECL(int) DBGFR3MemScan(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign, +VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign, const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress); -VMMR3DECL(int) DBGFR3MemRead(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead); -VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf); -VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead); +VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead); +VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf); +VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead); #endif @@ -979,7 +995,7 @@ VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, vo /** The mask of bits controlling the paging mode. */ #define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32) /** @} */ -VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr, +VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); @@ -993,7 +1009,7 @@ VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_ /** If currently executing in in 64-bit mode, blow up data selectors. */ #define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2) /** @} */ -VMMR3DECL(int) DBGFR3SelQueryInfo(PVM pVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo); +VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo); /** @@ -1269,6 +1285,11 @@ typedef DBGFREGVALTYPE *PDBGFREGVALTYPE; */ typedef union DBGFREGVAL { + uint64_t au64[2]; /**< The 64-bit array view. First because of the initializer. */ + uint32_t au32[4]; /**< The 32-bit array view. */ + uint16_t au16[8]; /**< The 16-bit array view. */ + uint8_t au8[16]; /**< The 8-bit array view. */ + uint8_t u8; /**< The 8-bit view. */ uint16_t u16; /**< The 16-bit view. */ uint32_t u32; /**< The 32-bit view. */ @@ -1285,10 +1306,6 @@ typedef union DBGFREGVAL uint32_t u32Limit; } dtr; - uint8_t au8[16]; /**< The 8-bit array view. */ - uint16_t au16[8]; /**< The 16-bit array view. */ - uint32_t au32[4]; /**< The 32-bit array view. */ - uint64_t au64[2]; /**< The 64-bit array view. */ RTUINT128U u; } DBGFREGVAL; /** Pointer to a generic register value type. */ @@ -1296,6 +1313,12 @@ typedef DBGFREGVAL *PDBGFREGVAL; /** Pointer to a const generic register value type. */ typedef DBGFREGVAL const *PCDBGFREGVAL; +/** Initialize a DBGFREGVAL variable to all zeros. */ +#define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0 } } +/** Initialize a DBGFREGVAL variable to all bits set . */ +#define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX } } + + VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial); VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags); @@ -1316,9 +1339,13 @@ typedef struct DBGFREGSUBFIELD int8_t cShift; /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */ uint8_t fFlags; - /** Getter (optional). */ + /** Getter (optional). + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue); - /** Setter (optional). */ + /** Setter (optional). + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask); } DBGFREGSUBFIELD; /** Pointer to a const register sub-field descriptor. */ @@ -1336,6 +1363,9 @@ typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD; /** Macro for creating a read-write sub-field entry with getters. */ #define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \ { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet } +/** Macro for creating a read-only sub-field entry without getters. */ +#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \ + { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ } /** Macro for creating a terminator sub-field entry. */ #define DBGFREGSUBFIELD_TERMINATOR() \ { NULL, 0, 0, 0, 0, NULL, NULL } @@ -1370,9 +1400,13 @@ typedef struct DBGFREGDESC * For CPU registers this is the offset into the CPUMCTX structure, * thuse the 'off' prefix. */ uint32_t offRegister; - /** Getter. */ + /** Getter. + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue); - /** Setter. */ + /** Setter. + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask); /** Aliases (optional). */ PCDBGFREGALIAS paAliases; @@ -1430,30 +1464,31 @@ typedef DBGFREGENTRY const *PCDBGFREGENTRY; * guest. */ #define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000) -VMMR3DECL(int) DBGFR3RegCpuQueryU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8); -VMMR3DECL(int) DBGFR3RegCpuQueryU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16); -VMMR3DECL(int) DBGFR3RegCpuQueryU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32); -VMMR3DECL(int) DBGFR3RegCpuQueryU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64); -VMMR3DECL(int) DBGFR3RegCpuQueryU128(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128); -VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd); -VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit); +VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8); +VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16); +VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32); +VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64); +VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128); +VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd); +VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit); #if 0 -VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PVM pVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); -VMMR3DECL(int) DBGFR3RegCpuQueryAll( PVM pVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); - -VMMR3DECL(int) DBGFR3RegCpuSetU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8); -VMMR3DECL(int) DBGFR3RegCpuSetU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16); -VMMR3DECL(int) DBGFR3RegCpuSetU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32); -VMMR3DECL(int) DBGFR3RegCpuSetU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64); -VMMR3DECL(int) DBGFR3RegCpuSetU128( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128); -VMMR3DECL(int) DBGFR3RegCpuSetLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd); -VMMR3DECL(int) DBGFR3RegCpuSetBatch( PVM pVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); + +VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8); +VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16); +VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32); +VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64); +VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128); +VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd); +VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs); #endif -VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType); +VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType); VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs); -VMMR3DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, const char *pszPrefix, uint32_t iInstance); +VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, + const char *pszPrefix, uint32_t iInstance); /** * Entry in a named batch query or set operation. @@ -1472,33 +1507,33 @@ typedef DBGFREGENTRYNM *PDBGFREGENTRYNM; /** Pointer to a const named register entry in a batch operation. */ typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM; -VMMR3DECL(int) DBGFR3RegNmValidate( PVM pVM, VMCPUID idDefCpu, const char *pszReg); - -VMMR3DECL(int) DBGFR3RegNmQuery( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType); -VMMR3DECL(int) DBGFR3RegNmQueryU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8); -VMMR3DECL(int) DBGFR3RegNmQueryU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16); -VMMR3DECL(int) DBGFR3RegNmQueryU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32); -VMMR3DECL(int) DBGFR3RegNmQueryU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64); -VMMR3DECL(int) DBGFR3RegNmQueryU128(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128); -/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/ -VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit); -VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs); -VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs); -VMMR3DECL(int) DBGFR3RegNmQueryAll( PVM pVM, PDBGFREGENTRYNM paRegs, size_t cRegs); - -VMMR3DECL(int) DBGFR3RegNmSet( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType); -VMMR3DECL(int) DBGFR3RegNmSetU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8); -VMMR3DECL(int) DBGFR3RegNmSetU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16); -VMMR3DECL(int) DBGFR3RegNmSetU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32); -VMMR3DECL(int) DBGFR3RegNmSetU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64); -VMMR3DECL(int) DBGFR3RegNmSetU128( PVM pVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128); -VMMR3DECL(int) DBGFR3RegNmSetLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double lrd); -VMMR3DECL(int) DBGFR3RegNmSetBatch( PVM pVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg); + +VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType); +VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8); +VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16); +VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32); +VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64); +VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128); +/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/ +VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit); +VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs); +VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs); + +VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType); +VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8); +VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16); +VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32); +VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64); +VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128); +VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd); +VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs); /** @todo add enumeration methods. */ -VMMR3DECL(int) DBGFR3RegPrintf( PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...); -VMMR3DECL(int) DBGFR3RegPrintfV(PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va); +VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...); +VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va); /** @@ -1546,18 +1581,18 @@ typedef struct DBGFOSREG * Constructs the instance. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(int, pfnConstruct)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(int, pfnConstruct)(PUVM pUVM, void *pvData); /** * Destroys the instance. * - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(void, pfnDestruct)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(void, pfnDestruct)(PUVM pUVM, void *pvData); /** * Probes the guest memory for OS finger prints. @@ -1566,10 +1601,10 @@ typedef struct DBGFOSREG * or pfnRefresh that should take care of that. * * @returns true if is an OS handled by this module, otherwise false. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(bool, pfnProbe)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(bool, pfnProbe)(PUVM pUVM, void *pvData); /** * Initializes a fresly detected guest, loading symbols and such useful stuff. @@ -1577,10 +1612,10 @@ typedef struct DBGFOSREG * This is called after pfnProbe. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(int, pfnInit)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(int, pfnInit)(PUVM pUVM, void *pvData); /** * Refreshes symbols and stuff following a redetection of the same OS. @@ -1588,10 +1623,10 @@ typedef struct DBGFOSREG * This is called after pfnProbe. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(int, pfnRefresh)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(int, pfnRefresh)(PUVM pUVM, void *pvData); /** * Terminates an OS when a new (or none) OS has been detected, @@ -1599,10 +1634,10 @@ typedef struct DBGFOSREG * * This is called after pfnProbe and if needed before pfnDestruct. * - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(void, pfnTerm)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(void, pfnTerm)(PUVM pUVM, void *pvData); /** * Queries the version of the running OS. @@ -1610,12 +1645,12 @@ typedef struct DBGFOSREG * This is only called after pfnInit(). * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. * @param pszVersion Where to store the version string. * @param cchVersion The size of the version string buffer. */ - DECLCALLBACKMEMBER(int, pfnQueryVersion)(PVM pVM, void *pvData, char *pszVersion, size_t cchVersion); + DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion); /** * Queries the pointer to a interface. @@ -1623,11 +1658,11 @@ typedef struct DBGFOSREG * This is called after pfnProbe. * * @returns Pointer to the interface if available, NULL if not available. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. * @param enmIf The interface identifier. */ - DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf); + DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf); /** Trailing magic (DBGFOSREG_MAGIC). */ uint32_t u32EndMagic; @@ -1640,14 +1675,14 @@ typedef DBGFOSREG const *PCDBGFOSREG; /** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */ #define DBGFOSREG_MAGIC 0x19830808 -VMMR3DECL(int) DBGFR3OSRegister(PVM pVM, PCDBGFOSREG pReg); -VMMR3DECL(int) DBGFR3OSDeregister(PVM pVM, PCDBGFOSREG pReg); -VMMR3DECL(int) DBGFR3OSDetect(PVM pVM, char *pszName, size_t cchName); -VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PVM pVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion); -VMMR3DECL(void *) DBGFR3OSQueryInterface(PVM pVM, DBGFOSINTERFACE enmIf); +VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg); +VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg); +VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName); +VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion); +VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf); -VMMR3DECL(int) DBGFR3CoreWrite(PVM pVM, const char *pszFilename, bool fReplaceFile); +VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile); /** @} */ diff --git a/include/VBox/vmm/dbgfsel.h b/include/VBox/vmm/dbgfsel.h index 708666bf..2be4ee84 100644 --- a/include/VBox/vmm/dbgfsel.h +++ b/include/VBox/vmm/dbgfsel.h @@ -3,7 +3,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/include/VBox/vmm/em.h b/include/VBox/vmm/em.h index a0efe5fc..d492ecf4 100644 --- a/include/VBox/vmm/em.h +++ b/include/VBox/vmm/em.h @@ -3,7 +3,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; @@ -51,9 +51,9 @@ typedef enum EMSTATE /** Raw-mode execution. */ EMSTATE_RAW, /** Hardware accelerated raw-mode execution. */ - EMSTATE_HWACC, - /** Value reserved for future use (used to be PARAV). */ - EMSTATE_RESERVED, + EMSTATE_HM, + /** Executing in IEM. */ + EMSTATE_IEM, /** Recompiled mode execution. */ EMSTATE_REM, /** Execution is halted. (waiting for interrupt) */ @@ -67,13 +67,18 @@ typedef enum EMSTATE /** Guest debug event from raw-mode is being processed. */ EMSTATE_DEBUG_GUEST_RAW, /** Guest debug event from hardware accelerated mode is being processed. */ - EMSTATE_DEBUG_GUEST_HWACC, + EMSTATE_DEBUG_GUEST_HM, + /** Guest debug event from interpreted execution mode is being processed. */ + EMSTATE_DEBUG_GUEST_IEM, /** Guest debug event from recompiled-mode is being processed. */ EMSTATE_DEBUG_GUEST_REM, /** Hypervisor debug event being processed. */ EMSTATE_DEBUG_HYPER, /** The VM has encountered a fatal error. (And everyone is panicing....) */ EMSTATE_GURU_MEDITATION, + /** Executing in IEM, falling back on REM if we cannot switch back to HM or + * RAW after a short while. */ + EMSTATE_IEM_THEN_REM, /** Just a hack to ensure that we get a 32-bit integer. */ EMSTATE_MAKE_32BIT_HACK = 0x7fffffff } EMSTATE; @@ -94,8 +99,8 @@ typedef enum EMCODETYPE_32BIT_HACK = 0x7fffffff } EMCODETYPE; -VMMDECL(EMSTATE) EMGetState(PVMCPU pVCpu); -VMMDECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState); +VMM_INT_DECL(EMSTATE) EMGetState(PVMCPU pVCpu); +VMM_INT_DECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState); /** @name Callback handlers for instruction emulation functions. * These are placed here because IOM wants to use them as well. @@ -121,7 +126,7 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; * @returns false if disabled. * @param pVM The VM to operate on. */ -#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser) +#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser) /** * Checks if raw ring-0 execute mode is enabled. @@ -130,7 +135,20 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; * @returns false if disabled. * @param pVM The VM to operate on. */ -#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor) +#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor) + +#ifdef VBOX_WITH_RAW_RING1 +/** + * Checks if raw ring-1 execute mode is enabled. + * + * @returns true if enabled. + * @returns false if disabled. + * @param pVM The VM to operate on. + */ +# define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled) +#else +# define EMIsRawRing1Enabled(pVM) false +#endif /** * Checks if execution with hardware assisted virtualization is enabled. @@ -139,7 +157,7 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; * @returns false if disabled. * @param pVM The VM to operate on. */ -#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser) +#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser) /** * Checks if execution of supervisor code should be done in the @@ -151,39 +169,39 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; */ #define EMIsSupervisorCodeRecompiled(pVM) ((pVM)->fRecompileSupervisor) -VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC); -VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu); -VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr); -VMMDECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore, - PDISCPUSTATE pDISState, unsigned *pcbInstr); -VMMDECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault); -VMMDECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten); -VMMDECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault, EMCODETYPE enmCodeType); +VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC); +VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu); +VMM_INT_DECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr); +VMM_INT_DECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore, + PDISCPUSTATE pDISState, unsigned *pcbInstr); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx, + RTGCPTR pvFault, EMCODETYPE enmCodeType); #ifdef IN_RC -VMMDECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); #endif -VMMDECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMDECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC); -VMMDECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen); -VMMDECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx); -VMMDECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen); -VMMDECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx); -VMMDECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data); -VMMDECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu); -#ifndef VBOX_WITH_IEM -VMMDECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -#endif /* !VBOX_WITH_IEM */ -VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx); -VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx); -VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx); +VMM_INT_DECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen); +VMM_INT_DECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx); +VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen); +VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx); +VMM_INT_DECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data); +VMM_INT_DECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu); +VMM_INT_DECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx); +VMM_INT_DECL(bool) EMMonitorWaitShouldContinue(PVMCPU pVCpu, PCPUMCTX pCtx); +VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx, RTGCPHYS GCPhys); +VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx); /** @name Assembly routines * @{ */ @@ -213,26 +231,28 @@ VMMDECL(uint32_t) EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbO /** @name REM locking routines * @{ */ -VMMDECL(void) EMRemUnlock(PVM pVM); -VMMDECL(void) EMRemLock(PVM pVM); -VMMDECL(bool) EMRemIsLockOwner(PVM pVM); -VMMDECL(int) EMRemTryLock(PVM pVM); +VMMDECL(void) EMRemUnlock(PVM pVM); +VMMDECL(void) EMRemLock(PVM pVM); +VMMDECL(bool) EMRemIsLockOwner(PVM pVM); +VMM_INT_DECL(int) EMRemTryLock(PVM pVM); /** @} */ + +/** @name EM_ONE_INS_FLAGS_XXX - flags for EMR3HmSingleInstruction (et al). + * @{ */ +/** Return when CS:RIP changes or some other important event happens. + * This means running whole REP and LOOP $ sequences for instance. */ +#define EM_ONE_INS_FLAGS_RIP_CHANGE RT_BIT_32(0) +/** Mask of valid flags. */ +#define EM_ONE_INS_FLAGS_MASK UINT32_C(0x00000001) +/** @} */ + + #ifdef IN_RING3 /** @defgroup grp_em_r3 The EM Host Context Ring-3 API * @ingroup grp_em * @{ */ -VMMR3DECL(int) EMR3Init(PVM pVM); -VMMR3DECL(void) EMR3Relocate(PVM pVM); -VMMR3DECL(void) EMR3ResetCpu(PVMCPU pVCpu); -VMMR3DECL(void) EMR3Reset(PVM pVM); -VMMR3DECL(int) EMR3Term(PVM pVM); -VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc); -VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(int) EMR3Interpret(PVM pVM); /** * Command argument for EMR3RawSetMode(). @@ -248,25 +268,30 @@ typedef enum EMEXECPOLICY EMEXECPOLICY_RECOMPILE_RING0, /** Whether to recompile ring-3 code or execute it in raw/hm. */ EMEXECPOLICY_RECOMPILE_RING3, + /** Whether to only use IEM for execution. */ + EMEXECPOLICY_IEM_ALL, /** End of valid value (not included). */ EMEXECPOLICY_END, /** The customary 32-bit type blowup. */ EMEXECPOLICY_32BIT_HACK = 0x7fffffff } EMEXECPOLICY; +VMMR3DECL(int) EMR3SetExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool fEnforce); +VMMR3DECL(int) EMR3QueryExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool *pfEnforced); -VMMR3DECL(int) EMR3SetExecutionPolicy(PVM pVM, EMEXECPOLICY enmPolicy, bool fEnforce); -/** @} */ -#endif /* IN_RING3 */ - +VMMR3_INT_DECL(int) EMR3Init(PVM pVM); +VMMR3_INT_DECL(void) EMR3Relocate(PVM pVM); +VMMR3_INT_DECL(void) EMR3ResetCpu(PVMCPU pVCpu); +VMMR3_INT_DECL(void) EMR3Reset(PVM pVM); +VMMR3_INT_DECL(int) EMR3Term(PVM pVM); +VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc); +VMMR3_INT_DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) EMR3NotifyResume(PVM pVM); +VMMR3_INT_DECL(int) EMR3NotifySuspend(PVM pVM); +VMMR3_INT_DECL(VBOXSTRICTRC) EMR3HmSingleInstruction(PVM pVM, PVMCPU pVCpu, uint32_t fFlags); -#ifdef IN_RC -/** @defgroup grp_em_gc The EM Guest Context API - * @ingroup grp_em - * @{ - */ -VMMRCDECL(int) EMGCTrap(PVM pVM, unsigned uTrap, PCPUMCTXCORE pRegFrame); /** @} */ -#endif /* IN_RC */ +#endif /* IN_RING3 */ /** @} */ diff --git a/include/VBox/vmm/ftm.h b/include/VBox/vmm/ftm.h index 2fc1ccfe..e8702d67 100644 --- a/include/VBox/vmm/ftm.h +++ b/include/VBox/vmm/ftm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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; @@ -40,24 +40,27 @@ RT_C_DECLS_BEGIN */ typedef enum FTMCHECKPOINTTYPE { + FTMCHECKPOINTTYPE_INVALID = 0, FTMCHECKPOINTTYPE_NETWORK, FTMCHECKPOINTTYPE_STORAGE, + FTMCHECKPOINTTYPE_END, FTMCHECKPOINTTYPE_32BIT_HACK = 0x7fffffff } FTMCHECKPOINTTYPE; -VMMDECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM); -VMMDECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); +VMM_INT_DECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM); +VMM_INT_DECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); #ifdef IN_RING3 /** @defgroup grp_ftm_r3 The FTM Host Context Ring-3 API * @ingroup grp_ftm * @{ */ -VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword); -VMMR3DECL(int) FTMR3Init(PVM pVM); -VMMR3DECL(int) FTMR3Term(PVM pVM); -VMMR3DECL(int) FTMR3CancelStandby(PVM pVM); -VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); +VMMR3DECL(int) FTMR3PowerOn(PUVM pUVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword); +VMMR3DECL(int) FTMR3CancelStandby(PUVM pUVM); + +VMMR3_INT_DECL(int) FTMR3Init(PVM pVM); +VMMR3_INT_DECL(int) FTMR3Term(PVM pVM); +VMMR3_INT_DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); #endif /* IN_RING3 */ diff --git a/include/VBox/vmm/gmm.h b/include/VBox/vmm/gmm.h index 0f93c94a..e5db104c 100644 --- a/include/VBox/vmm/gmm.h +++ b/include/VBox/vmm/gmm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-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/include/VBox/vmm/gvm.h b/include/VBox/vmm/gvm.h index b0d607de..0fe406b0 100644 --- a/include/VBox/vmm/gvm.h +++ b/include/VBox/vmm/gvm.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007-2010 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/include/VBox/vmm/gvmm.h b/include/VBox/vmm/gvmm.h index e78d181b..eb86f9b2 100644 --- a/include/VBox/vmm/gvmm.h +++ b/include/VBox/vmm/gvmm.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-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/include/VBox/vmm/hm.h b/include/VBox/vmm/hm.h new file mode 100644 index 00000000..12b94167 --- /dev/null +++ b/include/VBox/vmm/hm.h @@ -0,0 +1,265 @@ +/** @file + * HM - Intel/AMD VM Hardware Assisted Virtualization Manager (VMM) + */ + +/* + * 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; + * 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 ___VBox_vmm_hm_h +#define ___VBox_vmm_hm_h + +#include +#include +#include +#include + + +/** @defgroup grp_hm The VM Hardware Manager API + * @{ + */ + +RT_C_DECLS_BEGIN + +/** + * Checks whether HM (VT-x/AMD-V) is being used by this VM. + * + * @retval @c true if used. + * @retval @c false if software virtualization (raw-mode) is used. + * + * @param a_pVM The cross context VM structure. + * @sa HMIsEnabledNotMacro, HMR3IsEnabled + * @internal + */ +#if defined(VBOX_STRICT) && defined(IN_RING3) +# define HMIsEnabled(a_pVM) HMIsEnabledNotMacro(a_pVM) +#else +# define HMIsEnabled(a_pVM) ((a_pVM)->fHMEnabled) +#endif + +/** + * Checks whether raw-mode context is required for any purpose. + * + * @retval @c true if required either by raw-mode itself or by HM for doing + * switching the cpu to 64-bit mode. + * @retval @c false if not required. + * + * @param a_pVM The cross context VM structure. + * @internal + */ +#if HC_ARCH_BITS == 64 +# define HMIsRawModeCtxNeeded(a_pVM) (!HMIsEnabled(a_pVM)) +#else +# define HMIsRawModeCtxNeeded(a_pVM) (!HMIsEnabled(a_pVM) || (a_pVM)->fHMNeedRawModeCtx) +#endif + + /** + * Check if the current CPU state is valid for emulating IO blocks in the recompiler + * + * @returns boolean + * @param a_pVCpu Pointer to the shared virtual CPU structure. + * @internal + */ +#define HMCanEmulateIoBlock(a_pVCpu) (!CPUMIsGuestInPagedProtectedMode(a_pVCpu)) + + /** + * Check if the current CPU state is valid for emulating IO blocks in the recompiler + * + * @returns boolean + * @param a_pCtx Pointer to the CPU context (within PVM). + * @internal + */ +#define HMCanEmulateIoBlockEx(a_pCtx) (!CPUMIsGuestInPagedProtectedModeEx(a_pCtx)) + +/** + * Checks whether we're in the special hardware virtualization context. + * @returns true / false. + * @param a_pVCpu The caller's cross context virtual CPU structure. + * @thread EMT + */ +#ifdef IN_RING0 +# define HMIsInHwVirtCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_HM) +#else +# define HMIsInHwVirtCtx(a_pVCpu) (false) +#endif + +/** + * Checks whether we're in the special hardware virtualization context and we + * cannot perform long jump without guru meditating and possibly messing up the + * host and/or guest state. + * + * This is after we've turned interrupts off and such. + * + * @returns true / false. + * @param a_pVCpu The caller's cross context virtual CPU structure. + * @thread EMT + */ +#ifdef IN_RING0 +# define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_EXEC) +#else +# define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (false) +#endif + +/** + * 64-bit raw-mode (intermediate memory context) operations. + * + * These are special hypervisor eip values used when running 64-bit guests on + * 32-bit hosts. Each operation corresponds to a routine. + * + * @note Duplicated in the assembly code! + */ +typedef enum HM64ON32OP +{ + HM64ON32OP_INVALID = 0, + HM64ON32OP_VMXRCStartVM64, + HM64ON32OP_SVMRCVMRun64, + HM64ON32OP_HMRCSaveGuestFPU64, + HM64ON32OP_HMRCSaveGuestDebug64, + HM64ON32OP_HMRCTestSwitcher64, + HM64ON32OP_END, + HM64ON32OP_32BIT_HACK = 0x7fffffff +} HM64ON32OP; + +VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM); +VMM_INT_DECL(int) HMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt); +VMM_INT_DECL(bool) HMHasPendingIrq(PVM pVM); +VMM_INT_DECL(PX86PDPE) HMGetPaePdpes(PVMCPU pVCpu); +VMM_INT_DECL(int) HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping); +VMM_INT_DECL(bool) HMSetSingleInstruction(PVMCPU pVCpu, bool fEnable); + +#ifndef IN_RC +VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu); +VMM_INT_DECL(int) HMFlushTLBOnAllVCpus(PVM pVM); +VMM_INT_DECL(int) HMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt); +VMM_INT_DECL(int) HMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys); +VMM_INT_DECL(bool) HMIsNestedPagingActive(PVM pVM); +VMM_INT_DECL(PGMMODE) HMGetShwPagingMode(PVM pVM); +#else /* Nops in RC: */ +# define HMFlushTLB(pVCpu) do { } while (0) +# define HMIsNestedPagingActive(pVM) false +# define HMFlushTLBOnAllVCpus(pVM) do { } while (0) +#endif + +#ifdef IN_RING0 +/** @defgroup grp_hm_r0 The VM Hardware Manager API + * @ingroup grp_hm + * @{ + */ +VMMR0_INT_DECL(int) HMR0Init(void); +VMMR0_INT_DECL(int) HMR0Term(void); +VMMR0_INT_DECL(int) HMR0InitVM(PVM pVM); +VMMR0_INT_DECL(int) HMR0TermVM(PVM pVM); +VMMR0_INT_DECL(int) HMR0EnableAllCpus(PVM pVM); +VMMR0_INT_DECL(int) HMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled); +VMMR0_INT_DECL(void) HMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled); + +VMMR0_INT_DECL(void) HMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, + unsigned uPort, unsigned uAndVal, unsigned cbSize); +VMMR0_INT_DECL(void) HMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, + unsigned uPort, unsigned uAndVal, unsigned cbSize); + +/** @} */ +#endif /* IN_RING0 */ + + +#ifdef IN_RING3 +/** @defgroup grp_hm_r3 The VM Hardware Manager API + * @ingroup grp_hm + * @{ + */ +VMMR3DECL(bool) HMR3IsEnabled(PUVM pUVM); +VMMR3DECL(bool) HMR3IsNestedPagingActive(PUVM pUVM); +VMMR3DECL(bool) HMR3IsVpidActive(PUVM pVUM); +VMMR3DECL(bool) HMR3IsUXActive(PUVM pVUM); +VMMR3DECL(bool) HMR3IsSvmEnabled(PUVM pUVM); +VMMR3DECL(bool) HMR3IsVmxEnabled(PUVM pUVM); + +VMMR3_INT_DECL(bool) HMR3IsEventPending(PVMCPU pVCpu); +VMMR3_INT_DECL(int) HMR3Init(PVM pVM); +VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); +VMMR3_INT_DECL(void) HMR3Relocate(PVM pVM); +VMMR3_INT_DECL(int) HMR3Term(PVM pVM); +VMMR3_INT_DECL(void) HMR3Reset(PVM pVM); +VMMR3_INT_DECL(void) HMR3ResetCpu(PVMCPU pVCpu); +VMMR3_INT_DECL(void) HMR3CheckError(PVM pVM, int iStatusCode); +VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(void) HMR3NotifyScheduled(PVMCPU pVCpu); +VMMR3_INT_DECL(void) HMR3NotifyEmulated(PVMCPU pVCpu); +VMMR3_INT_DECL(bool) HMR3IsActive(PVMCPU pVCpu); +VMMR3_INT_DECL(void) HMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode); +VMMR3_INT_DECL(int) HMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(VBOXSTRICTRC) HMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR3_INT_DECL(int) HMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); +VMMR3_INT_DECL(int) HMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); +VMMR3_INT_DECL(int) HMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR3_INT_DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM); + +/** @} */ +#endif /* IN_RING3 */ + +#ifdef IN_RING0 +/** @addtogroup grp_hm_r0 + * @{ + */ +/** Disables preemption if required. */ +# define HM_DISABLE_PREEMPT_IF_NEEDED() \ + RTTHREADPREEMPTSTATE PreemptStateInternal = RTTHREADPREEMPTSTATE_INITIALIZER; \ + bool fPreemptDisabledInternal = false; \ + if (RTThreadPreemptIsEnabled(NIL_RTTHREAD)) \ + { \ + Assert(VMMR0ThreadCtxHooksAreRegistered(pVCpu)); \ + RTThreadPreemptDisable(&PreemptStateInternal); \ + fPreemptDisabledInternal = true; \ + } + +/** Restores preemption if previously disabled by HM_DISABLE_PREEMPT(). */ +# define HM_RESTORE_PREEMPT_IF_NEEDED() \ + do \ + { \ + if (fPreemptDisabledInternal) \ + RTThreadPreemptRestore(&PreemptStateInternal); \ + } while (0) + +VMMR0_INT_DECL(int) HMR0SetupVM(PVM pVM); +VMMR0_INT_DECL(int) HMR0RunGuestCode(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0Enter(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0Leave(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0EnterCpu(PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0LeaveCpu(PVMCPU pVCpu); +VMMR0_INT_DECL(void) HMR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, void *pvUser); +VMMR0_INT_DECL(bool) HMR0SuspendPending(void); + +# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) +VMMR0_INT_DECL(int) HMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) HMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) HMR0TestSwitcher3264(PVM pVM); +# endif + +/** @} */ +#endif /* IN_RING0 */ + + +/** @} */ +RT_C_DECLS_END + + +#endif + diff --git a/include/VBox/vmm/hm_svm.h b/include/VBox/vmm/hm_svm.h new file mode 100644 index 00000000..7a67c387 --- /dev/null +++ b/include/VBox/vmm/hm_svm.h @@ -0,0 +1,811 @@ +/** @file + * HM - SVM Structures and Definitions. (VMM) + */ + +/* + * 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; + * 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 ___VBox_vmm_svm_h +#define ___VBox_vmm_svm_h + +#include +#include +#include +#include + +/** @defgroup grp_svm svm Types and Definitions + * @ingroup grp_hm + * @{ + */ + +/** @name SVM features for cpuid 0x8000000a + * @{ + */ +/** Bit 0 - NP - Nested Paging supported. */ +#define AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING RT_BIT(0) +/** Bit 1 - LbrVirt - Support for saving five debug MSRs. */ +#define AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT RT_BIT(1) +/** Bit 2 - SVML - SVM locking bit supported. */ +#define AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK RT_BIT(2) +/** Bit 3 - NRIPS - Saving the next instruction pointer is supported. */ +#define AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE RT_BIT(3) +/** Bit 4 - TscRateMsr - Support for MSR TSC ratio. */ +#define AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR RT_BIT(4) +/** Bit 5 - VmcbClean - Support VMCB clean bits. */ +#define AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN RT_BIT(5) +/** Bit 6 - FlushByAsid - Indicate TLB flushing for current ASID only, and that + * VMCB.TLB_Control is supported. */ +#define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID RT_BIT(6) +/** Bit 7 - DecodeAssist - Indicate decode assist is supported. */ +#define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST RT_BIT(7) +/** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */ +#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER RT_BIT(10) +/** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE + * intercept filter cycle count threshold. */ +#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD RT_BIT(12) +/** Bit 13 - AVIC - Advanced Virtual Interrupt Controller. */ +#define AMD_CPUID_SVM_FEATURE_EDX_AVIC RT_BIT(13) +/** @} */ + + +/** @name SVM Basic Exit Reasons. + * @{ + */ +/** Invalid guest state in VMCB. */ +#define SVM_EXIT_INVALID (-1) +/** Read from CR0-CR15. */ +#define SVM_EXIT_READ_CR0 0x0 +#define SVM_EXIT_READ_CR1 0x1 +#define SVM_EXIT_READ_CR2 0x2 +#define SVM_EXIT_READ_CR3 0x3 +#define SVM_EXIT_READ_CR4 0x4 +#define SVM_EXIT_READ_CR5 0x5 +#define SVM_EXIT_READ_CR6 0x6 +#define SVM_EXIT_READ_CR7 0x7 +#define SVM_EXIT_READ_CR8 0x8 +#define SVM_EXIT_READ_CR9 0x9 +#define SVM_EXIT_READ_CR10 0xA +#define SVM_EXIT_READ_CR11 0xB +#define SVM_EXIT_READ_CR12 0xC +#define SVM_EXIT_READ_CR13 0xD +#define SVM_EXIT_READ_CR14 0xE +#define SVM_EXIT_READ_CR15 0xF +/** Writes to CR0-CR15. */ +#define SVM_EXIT_WRITE_CR0 0x10 +#define SVM_EXIT_WRITE_CR1 0x11 +#define SVM_EXIT_WRITE_CR2 0x12 +#define SVM_EXIT_WRITE_CR3 0x13 +#define SVM_EXIT_WRITE_CR4 0x14 +#define SVM_EXIT_WRITE_CR5 0x15 +#define SVM_EXIT_WRITE_CR6 0x16 +#define SVM_EXIT_WRITE_CR7 0x17 +#define SVM_EXIT_WRITE_CR8 0x18 +#define SVM_EXIT_WRITE_CR9 0x19 +#define SVM_EXIT_WRITE_CR10 0x1A +#define SVM_EXIT_WRITE_CR11 0x1B +#define SVM_EXIT_WRITE_CR12 0x1C +#define SVM_EXIT_WRITE_CR13 0x1D +#define SVM_EXIT_WRITE_CR14 0x1E +#define SVM_EXIT_WRITE_CR15 0x1F +/** Read from DR0-DR15. */ +#define SVM_EXIT_READ_DR0 0x20 +#define SVM_EXIT_READ_DR1 0x21 +#define SVM_EXIT_READ_DR2 0x22 +#define SVM_EXIT_READ_DR3 0x23 +#define SVM_EXIT_READ_DR4 0x24 +#define SVM_EXIT_READ_DR5 0x25 +#define SVM_EXIT_READ_DR6 0x26 +#define SVM_EXIT_READ_DR7 0x27 +#define SVM_EXIT_READ_DR8 0x28 +#define SVM_EXIT_READ_DR9 0x29 +#define SVM_EXIT_READ_DR10 0x2A +#define SVM_EXIT_READ_DR11 0x2B +#define SVM_EXIT_READ_DR12 0x2C +#define SVM_EXIT_READ_DR13 0x2D +#define SVM_EXIT_READ_DR14 0x2E +#define SVM_EXIT_READ_DR15 0x2F +/** Writes to DR0-DR15. */ +#define SVM_EXIT_WRITE_DR0 0x30 +#define SVM_EXIT_WRITE_DR1 0x31 +#define SVM_EXIT_WRITE_DR2 0x32 +#define SVM_EXIT_WRITE_DR3 0x33 +#define SVM_EXIT_WRITE_DR4 0x34 +#define SVM_EXIT_WRITE_DR5 0x35 +#define SVM_EXIT_WRITE_DR6 0x36 +#define SVM_EXIT_WRITE_DR7 0x37 +#define SVM_EXIT_WRITE_DR8 0x38 +#define SVM_EXIT_WRITE_DR9 0x39 +#define SVM_EXIT_WRITE_DR10 0x3A +#define SVM_EXIT_WRITE_DR11 0x3B +#define SVM_EXIT_WRITE_DR12 0x3C +#define SVM_EXIT_WRITE_DR13 0x3D +#define SVM_EXIT_WRITE_DR14 0x3E +#define SVM_EXIT_WRITE_DR15 0x3F +/* Exception 0-31. */ +#define SVM_EXIT_EXCEPTION_0 0x40 +#define SVM_EXIT_EXCEPTION_1 0x41 +#define SVM_EXIT_EXCEPTION_2 0x42 +#define SVM_EXIT_EXCEPTION_3 0x43 +#define SVM_EXIT_EXCEPTION_4 0x44 +#define SVM_EXIT_EXCEPTION_5 0x45 +#define SVM_EXIT_EXCEPTION_6 0x46 +#define SVM_EXIT_EXCEPTION_7 0x47 +#define SVM_EXIT_EXCEPTION_8 0x48 +#define SVM_EXIT_EXCEPTION_9 0x49 +#define SVM_EXIT_EXCEPTION_A 0x4A +#define SVM_EXIT_EXCEPTION_B 0x4B +#define SVM_EXIT_EXCEPTION_C 0x4C +#define SVM_EXIT_EXCEPTION_D 0x4D +#define SVM_EXIT_EXCEPTION_E 0x4E +#define SVM_EXIT_EXCEPTION_F 0x4F +#define SVM_EXIT_EXCEPTION_10 0x50 +#define SVM_EXIT_EXCEPTION_11 0x51 +#define SVM_EXIT_EXCEPTION_12 0x52 +#define SVM_EXIT_EXCEPTION_13 0x53 +#define SVM_EXIT_EXCEPTION_14 0x54 +#define SVM_EXIT_EXCEPTION_15 0x55 +#define SVM_EXIT_EXCEPTION_16 0x56 +#define SVM_EXIT_EXCEPTION_17 0x57 +#define SVM_EXIT_EXCEPTION_18 0x58 +#define SVM_EXIT_EXCEPTION_19 0x59 +#define SVM_EXIT_EXCEPTION_1A 0x5A +#define SVM_EXIT_EXCEPTION_1B 0x5B +#define SVM_EXIT_EXCEPTION_1C 0x5C +#define SVM_EXIT_EXCEPTION_1D 0x5D +#define SVM_EXIT_EXCEPTION_1E 0x5E +#define SVM_EXIT_EXCEPTION_1F 0x5F +/** Physical maskable interrupt. */ +#define SVM_EXIT_INTR 0x60 +/** Non-maskable interrupt. */ +#define SVM_EXIT_NMI 0x61 +/** System Management interrupt. */ +#define SVM_EXIT_SMI 0x62 +/** Physical INIT signal. */ +#define SVM_EXIT_INIT 0x63 +/** Virtual interrupt. */ +#define SVM_EXIT_VINTR 0x64 +/** Write to CR0 that changed any bits other than CR0.TS or CR0.MP. */ +#define SVM_EXIT_CR0_SEL_WRITE 0x65 +/** IDTR read. */ +#define SVM_EXIT_IDTR_READ 0x66 +/** GDTR read. */ +#define SVM_EXIT_GDTR_READ 0x67 +/** LDTR read. */ +#define SVM_EXIT_LDTR_READ 0x68 +/** TR read. */ +#define SVM_EXIT_TR_READ 0x69 +/** IDTR write. */ +#define SVM_EXIT_IDTR_WRITE 0x6A +/** GDTR write. */ +#define SVM_EXIT_GDTR_WRITE 0x6B +/** LDTR write. */ +#define SVM_EXIT_LDTR_WRITE 0x6C +/** TR write. */ +#define SVM_EXIT_TR_WRITE 0x6D +/** RDTSC instruction. */ +#define SVM_EXIT_RDTSC 0x6E +/** RDPMC instruction. */ +#define SVM_EXIT_RDPMC 0x6F +/** PUSHF instruction. */ +#define SVM_EXIT_PUSHF 0x70 +/** POPF instruction. */ +#define SVM_EXIT_POPF 0x71 +/** CPUID instruction. */ +#define SVM_EXIT_CPUID 0x72 +/** RSM instruction. */ +#define SVM_EXIT_RSM 0x73 +/** IRET instruction. */ +#define SVM_EXIT_IRET 0x74 +/** software interrupt (INTn instructions). */ +#define SVM_EXIT_SWINT 0x75 +/** INVD instruction. */ +#define SVM_EXIT_INVD 0x76 +/** PAUSE instruction. */ +#define SVM_EXIT_PAUSE 0x77 +/** HLT instruction. */ +#define SVM_EXIT_HLT 0x78 +/** INVLPG instructions. */ +#define SVM_EXIT_INVLPG 0x79 +/** INVLPGA instruction. */ +#define SVM_EXIT_INVLPGA 0x7A +/** IN or OUT accessing protected port (the EXITINFO1 field provides more information). */ +#define SVM_EXIT_IOIO 0x7B +/** RDMSR or WRMSR access to protected MSR. */ +#define SVM_EXIT_MSR 0x7C +/** task switch. */ +#define SVM_EXIT_TASK_SWITCH 0x7D +/** FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt. */ +#define SVM_EXIT_FERR_FREEZE 0x7E +/** Shutdown. */ +#define SVM_EXIT_SHUTDOWN 0x7F +/** VMRUN instruction. */ +#define SVM_EXIT_VMRUN 0x80 +/** VMMCALL instruction. */ +#define SVM_EXIT_VMMCALL 0x81 +/** VMLOAD instruction. */ +#define SVM_EXIT_VMLOAD 0x82 +/** VMSAVE instruction. */ +#define SVM_EXIT_VMSAVE 0x83 +/** STGI instruction. */ +#define SVM_EXIT_STGI 0x84 +/** CLGI instruction. */ +#define SVM_EXIT_CLGI 0x85 +/** SKINIT instruction. */ +#define SVM_EXIT_SKINIT 0x86 +/** RDTSCP instruction. */ +#define SVM_EXIT_RDTSCP 0x87 +/** ICEBP instruction. */ +#define SVM_EXIT_ICEBP 0x88 +/** WBINVD instruction. */ +#define SVM_EXIT_WBINVD 0x89 +/** MONITOR instruction. */ +#define SVM_EXIT_MONITOR 0x8A +/** MWAIT instruction. */ +#define SVM_EXIT_MWAIT 0x8B +/** MWAIT instruction, when armed. */ +#define SVM_EXIT_MWAIT_ARMED 0x8C +/** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */ +#define SVM_EXIT_NPF 0x400 +/** AVIC: Virtual IPI delivery not completed. */ +#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 +/** AVIC: Attempted access by guest to a vAPIC register not handled by AVIC + * hardware. */ +#define SVM_EXIT_AVIC_NOACCEL 0x402 + +/** The maximum possible exit value. */ +#define SVM_EXIT_MAX (SVM_EXIT_AVIC_NOACCEL) +/** @} */ + + +/** @name SVMVMCB.u64ExitInfo2 for task switches + * @{ + */ +/** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */ +#define SVM_EXIT2_TASK_SWITCH_IRET RT_BIT_64(36) +/** Set to 1 if the task switch was caused by a far jump; else cleared to 0. */ +#define SVM_EXIT2_TASK_SWITCH_JMP RT_BIT_64(38) +/** Set to 1 if the task switch has an error code; else cleared to 0. */ +#define SVM_EXIT2_TASK_SWITCH_HAS_ERROR_CODE RT_BIT_64(44) +/** The value of EFLAGS.RF that would be saved in the outgoing TSS if the task switch were not intercepted. */ +#define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF RT_BIT_64(48) +/** @} */ + +/** @name SVMVMCB.u64ExitInfo1 for MSR accesses + * @{ + */ +/** The access was a read MSR. */ +#define SVM_EXIT1_MSR_READ 0x0 +/** The access was a write MSR. */ +#define SVM_EXIT1_MSR_WRITE 0x1 +/** @} */ + +/** @name SVMVMCB.ctrl.u32InterceptCtrl1 + * @{ + */ +/** 0 Intercept INTR (physical maskable interrupt). */ +#define SVM_CTRL1_INTERCEPT_INTR RT_BIT(0) +/** 1 Intercept NMI. */ +#define SVM_CTRL1_INTERCEPT_NMI RT_BIT(1) +/** 2 Intercept SMI. */ +#define SVM_CTRL1_INTERCEPT_SMI RT_BIT(2) +/** 3 Intercept INIT. */ +#define SVM_CTRL1_INTERCEPT_INIT RT_BIT(3) +/** 4 Intercept VINTR (virtual maskable interrupt). */ +#define SVM_CTRL1_INTERCEPT_VINTR RT_BIT(4) +/** 5 Intercept CR0 writes that change bits other than CR0.TS or CR0.MP */ +#define SVM_CTRL1_INTERCEPT_CR0 RT_BIT(5) +/** 6 Intercept reads of IDTR. */ +#define SVM_CTRL1_INTERCEPT_IDTR_READS RT_BIT(6) +/** 7 Intercept reads of GDTR. */ +#define SVM_CTRL1_INTERCEPT_GDTR_READS RT_BIT(7) +/** 8 Intercept reads of LDTR. */ +#define SVM_CTRL1_INTERCEPT_LDTR_READS RT_BIT(8) +/** 9 Intercept reads of TR. */ +#define SVM_CTRL1_INTERCEPT_TR_READS RT_BIT(9) +/** 10 Intercept writes of IDTR. */ +#define SVM_CTRL1_INTERCEPT_IDTR_WRITES RT_BIT(10) +/** 11 Intercept writes of GDTR. */ +#define SVM_CTRL1_INTERCEPT_GDTR_WRITES RT_BIT(11) +/** 12 Intercept writes of LDTR. */ +#define SVM_CTRL1_INTERCEPT_LDTR_WRITES RT_BIT(12) +/** 13 Intercept writes of TR. */ +#define SVM_CTRL1_INTERCEPT_TR_WRITES RT_BIT(13) +/** 14 Intercept RDTSC instruction. */ +#define SVM_CTRL1_INTERCEPT_RDTSC RT_BIT(14) +/** 15 Intercept RDPMC instruction. */ +#define SVM_CTRL1_INTERCEPT_RDPMC RT_BIT(15) +/** 16 Intercept PUSHF instruction. */ +#define SVM_CTRL1_INTERCEPT_PUSHF RT_BIT(16) +/** 17 Intercept POPF instruction. */ +#define SVM_CTRL1_INTERCEPT_POPF RT_BIT(17) +/** 18 Intercept CPUID instruction. */ +#define SVM_CTRL1_INTERCEPT_CPUID RT_BIT(18) +/** 19 Intercept RSM instruction. */ +#define SVM_CTRL1_INTERCEPT_RSM RT_BIT(19) +/** 20 Intercept IRET instruction. */ +#define SVM_CTRL1_INTERCEPT_IRET RT_BIT(20) +/** 21 Intercept INTn instruction. */ +#define SVM_CTRL1_INTERCEPT_INTN RT_BIT(21) +/** 22 Intercept INVD instruction. */ +#define SVM_CTRL1_INTERCEPT_INVD RT_BIT(22) +/** 23 Intercept PAUSE instruction. */ +#define SVM_CTRL1_INTERCEPT_PAUSE RT_BIT(23) +/** 24 Intercept HLT instruction. */ +#define SVM_CTRL1_INTERCEPT_HLT RT_BIT(24) +/** 25 Intercept INVLPG instruction. */ +#define SVM_CTRL1_INTERCEPT_INVLPG RT_BIT(25) +/** 26 Intercept INVLPGA instruction. */ +#define SVM_CTRL1_INTERCEPT_INVLPGA RT_BIT(26) +/** 27 IOIO_PROT Intercept IN/OUT accesses to selected ports. */ +#define SVM_CTRL1_INTERCEPT_INOUT_BITMAP RT_BIT(27) +/** 28 MSR_PROT Intercept RDMSR or WRMSR accesses to selected MSRs. */ +#define SVM_CTRL1_INTERCEPT_MSR_SHADOW RT_BIT(28) +/** 29 Intercept task switches. */ +#define SVM_CTRL1_INTERCEPT_TASK_SWITCH RT_BIT(29) +/** 30 FERR_FREEZE: intercept processor "freezing" during legacy FERR handling. */ +#define SVM_CTRL1_INTERCEPT_FERR_FREEZE RT_BIT(30) +/** 31 Intercept shutdown events. */ +#define SVM_CTRL1_INTERCEPT_SHUTDOWN RT_BIT(31) +/** @} */ + + +/** @name SVMVMCB.ctrl.u32InterceptCtrl2 + * @{ + */ +/** 0 Intercept VMRUN instruction. */ +#define SVM_CTRL2_INTERCEPT_VMRUN RT_BIT(0) +/** 1 Intercept VMMCALL instruction. */ +#define SVM_CTRL2_INTERCEPT_VMMCALL RT_BIT(1) +/** 2 Intercept VMLOAD instruction. */ +#define SVM_CTRL2_INTERCEPT_VMLOAD RT_BIT(2) +/** 3 Intercept VMSAVE instruction. */ +#define SVM_CTRL2_INTERCEPT_VMSAVE RT_BIT(3) +/** 4 Intercept STGI instruction. */ +#define SVM_CTRL2_INTERCEPT_STGI RT_BIT(4) +/** 5 Intercept CLGI instruction. */ +#define SVM_CTRL2_INTERCEPT_CLGI RT_BIT(5) +/** 6 Intercept SKINIT instruction. */ +#define SVM_CTRL2_INTERCEPT_SKINIT RT_BIT(6) +/** 7 Intercept RDTSCP instruction. */ +#define SVM_CTRL2_INTERCEPT_RDTSCP RT_BIT(7) +/** 8 Intercept ICEBP instruction. */ +#define SVM_CTRL2_INTERCEPT_ICEBP RT_BIT(8) +/** 9 Intercept WBINVD instruction. */ +#define SVM_CTRL2_INTERCEPT_WBINVD RT_BIT(9) +/** 10 Intercept MONITOR instruction. */ +#define SVM_CTRL2_INTERCEPT_MONITOR RT_BIT(10) +/** 11 Intercept MWAIT instruction unconditionally. */ +#define SVM_CTRL2_INTERCEPT_MWAIT RT_BIT(11) +/** 12 Intercept MWAIT instruction when armed. */ +#define SVM_CTRL2_INTERCEPT_MWAIT_ARMED RT_BIT(12) +/** 13 Intercept XSETBV instruction. */ +#define SVM_CTRL2_INTERCEPT_XSETBV RT_BIT(13) +/** @} */ + +/** @name SVMVMCB.ctrl.u64NestedPaging + * @{ + */ +#define SVM_NESTED_PAGING_ENABLE RT_BIT(0) +/** @} */ + +/** @name SVMVMCB.ctrl.u64IntShadow + * @{ + */ +#define SVM_INTERRUPT_SHADOW_ACTIVE RT_BIT(0) +/** @} */ + + +/** @name SVMINTCTRL.u3Type + * @{ + */ +/** External or virtual interrupt. */ +#define SVM_EVENT_EXTERNAL_IRQ 0 +/** Non-maskable interrupt. */ +#define SVM_EVENT_NMI 2 +/** Exception; fault or trap. */ +#define SVM_EVENT_EXCEPTION 3 +/** Software interrupt. */ +#define SVM_EVENT_SOFTWARE_INT 4 +/** @} */ + + +/** @name SVMVMCB.ctrl.TLBCtrl.n.u8TLBFlush + * @{ + */ +/** Flush nothing. */ +#define SVM_TLB_FLUSH_NOTHING 0 +/** Flush entire TLB (host+guest entries) */ +#define SVM_TLB_FLUSH_ENTIRE 1 +/** Flush this guest's TLB entries (by ASID) */ +#define SVM_TLB_FLUSH_SINGLE_CONTEXT 3 +/** Flush this guest's non-global TLB entries (by ASID) */ +#define SVM_TLB_FLUSH_SINGLE_CONTEXT_RETAIN_GLOBALS 7 +/** @} */ + + +/** + * SVM Selector type; includes hidden parts. + */ +#pragma pack(1) +typedef struct +{ + uint16_t u16Sel; + uint16_t u16Attr; + uint32_t u32Limit; + uint64_t u64Base; /**< Only lower 32 bits are implemented for CS, DS, ES & SS. */ +} SVMSEL; +#pragma pack() + +/** + * SVM GDTR/IDTR type. + */ +#pragma pack(1) +typedef struct +{ + uint16_t u16Reserved1; + uint16_t u16Reserved2; + uint32_t u32Limit; /**< Only lower 16 bits are implemented. */ + uint64_t u64Base; +} SVMGDTR; +#pragma pack() +typedef SVMGDTR SVMIDTR; + +/** + * SVM Event injection structure (EVENTINJ and EXITINTINFO). + */ +typedef union +{ + struct + { + uint32_t u8Vector : 8; + uint32_t u3Type : 3; + uint32_t u1ErrorCodeValid : 1; + uint32_t u19Reserved : 19; + uint32_t u1Valid : 1; + uint32_t u32ErrorCode : 32; + } n; + uint64_t u; +} SVMEVENT; +/** Pointer to the SVMEVENT union. */ +typedef SVMEVENT *PSVMEVENT; + +/** + * SVM Interrupt control structure (Virtual Interrupt Control). + */ +typedef union +{ + struct + { + uint32_t u8VTPR : 8; + uint32_t u1VIrqValid : 1; + uint32_t u7Reserved : 7; + uint32_t u4VIrqPriority : 4; + uint32_t u1IgnoreTPR : 1; + uint32_t u3Reserved : 3; + uint32_t u1VIrqMasking : 1; + uint32_t u6Reserved : 6; + uint32_t u1AvicEnable : 1; + uint32_t u8VIrqVector : 8; + uint32_t u24Reserved : 24; + } n; + uint64_t u; +} SVMINTCTRL; + +/** + * SVM TLB control structure. + */ +typedef union +{ + struct + { + uint32_t u32ASID : 32; + uint32_t u8TLBFlush : 8; + uint32_t u24Reserved : 24; + } n; + uint64_t u; +} SVMTLBCTRL; + +/** + * SVM IOIO exit structure (EXITINFO1 for IOIO intercepts). + */ +typedef union +{ + struct + { + uint32_t u1Type : 1; /**< 0 = out, 1 = in */ + uint32_t u1Reserved : 1; + uint32_t u1STR : 1; + uint32_t u1REP : 1; + uint32_t u1OP8 : 1; + uint32_t u1OP16 : 1; + uint32_t u1OP32 : 1; + uint32_t u1ADDR16 : 1; + uint32_t u1ADDR32 : 1; + uint32_t u1ADDR64 : 1; + uint32_t u6Reserved : 6; + uint32_t u16Port : 16; + } n; + uint32_t u; +} SVMIOIOEXIT; + +/** @name SVMIOIOEXIT.u1Type + * @{ */ +/** IO write. */ +#define SVM_IOIO_WRITE 0 +/** IO read. */ +#define SVM_IOIO_READ 1 +/** @}*/ + +/** + * SVM nested paging structure. + */ +typedef union +{ + struct + { + uint32_t u1NestedPaging : 1; /**< enabled/disabled */ + } n; + uint64_t u; +} SVMNPCTRL; + +/** + * SVM AVIC. + */ +typedef union +{ + struct + { + uint64_t u12Reserved1 : 12; + uint64_t u40Addr : 40; + uint64_t u12Reserved2 : 12; + } n; + uint64_t u; +} SVMAVIC; +AssertCompileSize(SVMAVIC, 8); + +/** + * SVM AVIC PHYSICAL_TABLE pointer. + */ +typedef union +{ + struct + { + uint64_t u8LastGuestCoreId : 8; + uint64_t u4Reserved : 4; + uint64_t u40Addr : 40; + uint64_t u12Reserved : 12; + } n; + uint64_t u; +} SVMAVICPHYS; +AssertCompileSize(SVMAVICPHYS, 8); + +/** + * SVM VM Control Block. (VMCB) + */ +#pragma pack(1) +typedef struct SVMVMCB +{ + /** Control Area. */ + struct + { + /** Offset 0x00 - Intercept reads of CR0-15. */ + uint16_t u16InterceptRdCRx; + /** Offset 0x02 - Intercept writes to CR0-15. */ + uint16_t u16InterceptWrCRx; + /** Offset 0x04 - Intercept reads of DR0-15. */ + uint16_t u16InterceptRdDRx; + /** Offset 0x06 - Intercept writes to DR0-15. */ + uint16_t u16InterceptWrDRx; + /** Offset 0x08 - Intercept exception vectors 0-31. */ + uint32_t u32InterceptException; + /** Offset 0x0C - Intercept control field 1. */ + uint32_t u32InterceptCtrl1; + /** Offset 0x0C - Intercept control field 2. */ + uint32_t u32InterceptCtrl2; + /** Offset 0x14-0x3F - Reserved. */ + uint8_t u8Reserved[0x3c - 0x14]; + /** Offset 0x3c - PAUSE filter threshold. */ + uint16_t u16PauseFilterThreshold; + /** Offset 0x3e - PAUSE intercept filter count. */ + uint16_t u16PauseFilterCount; + /** Offset 0x40 - Physical address of IOPM. */ + uint64_t u64IOPMPhysAddr; + /** Offset 0x48 - Physical address of MSRPM. */ + uint64_t u64MSRPMPhysAddr; + /** Offset 0x50 - TSC Offset. */ + uint64_t u64TSCOffset; + /** Offset 0x58 - TLB control field. */ + SVMTLBCTRL TLBCtrl; + /** Offset 0x60 - Interrupt control field. */ + SVMINTCTRL IntCtrl; + /** Offset 0x68 - Interrupt shadow. */ + uint64_t u64IntShadow; + /** Offset 0x70 - Exit code. */ + uint64_t u64ExitCode; + /** Offset 0x78 - Exit info 1. */ + uint64_t u64ExitInfo1; + /** Offset 0x80 - Exit info 2. */ + uint64_t u64ExitInfo2; + /** Offset 0x88 - Exit Interrupt info. */ + SVMEVENT ExitIntInfo; + /** Offset 0x90 - Nested Paging. */ + SVMNPCTRL NestedPaging; + /** Offset 0x98 - AVIC APIC BAR. */ + SVMAVIC AvicBar; + /** Offset 0xA0-0xA7 - Reserved. */ + uint8_t u8Reserved2[0xA8-0xA0]; + /** Offset 0xA8 - Event injection. */ + SVMEVENT EventInject; + /** Offset 0xB0 - Host CR3 for nested paging. */ + uint64_t u64NestedPagingCR3; + /** Offset 0xB8 - LBR Virtualization. */ + uint64_t u64LBRVirt; + /** Offset 0xC0 - VMCB Clean Bits. */ + uint64_t u64VmcbCleanBits; + /** Offset 0xC8 - Next sequential instruction pointer. */ + uint64_t u64NextRIP; + /** Offset 0xD0 - Number of bytes fetched. */ + uint8_t cbInstrFetched; + /** Offset 0xD1 - Number of bytes fetched. */ + uint8_t abInstr[15]; + /** Offset 0xE0 - AVIC APIC_BACKING_PAGE pointer. */ + SVMAVIC AvicBackingPagePtr; + /** Offset 0xE8-0xEF - Reserved. */ + uint8_t u8Reserved3[0xF0 - 0xE8]; + /** Offset 0xF0 - AVIC LOGICAL_TABLE pointer. */ + SVMAVIC AvicLogicalTablePtr; + /** Offset 0xF8 - AVIC PHYSICAL_TABLE pointer. */ + SVMAVICPHYS AvicPhysicalTablePtr; + } ctrl; + + /** Offset 0x100-0x3FF - Reserved. */ + uint8_t u8Reserved3[0x400-0x100]; + + /** State Save Area. Starts at offset 0x400. */ + struct + { + /** Offset 0x400 - Guest ES register + hidden parts. */ + SVMSEL ES; + /** Offset 0x410 - Guest CS register + hidden parts. */ + SVMSEL CS; + /** Offset 0x420 - Guest SS register + hidden parts. */ + SVMSEL SS; + /** Offset 0x430 - Guest DS register + hidden parts. */ + SVMSEL DS; + /** Offset 0x440 - Guest FS register + hidden parts. */ + SVMSEL FS; + /** Offset 0x450 - Guest GS register + hidden parts. */ + SVMSEL GS; + /** Offset 0x460 - Guest GDTR register. */ + SVMGDTR GDTR; + /** Offset 0x470 - Guest LDTR register + hidden parts. */ + SVMSEL LDTR; + /** Offset 0x480 - Guest IDTR register. */ + SVMIDTR IDTR; + /** Offset 0x490 - Guest TR register + hidden parts. */ + SVMSEL TR; + /** Offset 0x4A0-0x4CA - Reserved. */ + uint8_t u8Reserved4[0x4CB-0x4A0]; + /** Offset 0x4CB - CPL. */ + uint8_t u8CPL; + /** Offset 0x4CC-0x4CF - Reserved. */ + uint8_t u8Reserved5[0x4D0-0x4CC]; + /** Offset 0x4D0 - EFER. */ + uint64_t u64EFER; + /** Offset 0x4D8-0x547 - Reserved. */ + uint8_t u8Reserved6[0x548-0x4D8]; + /** Offset 0x548 - CR4. */ + uint64_t u64CR4; + /** Offset 0x550 - CR3. */ + uint64_t u64CR3; + /** Offset 0x558 - CR0. */ + uint64_t u64CR0; + /** Offset 0x560 - DR7. */ + uint64_t u64DR7; + /** Offset 0x568 - DR6. */ + uint64_t u64DR6; + /** Offset 0x570 - RFLAGS. */ + uint64_t u64RFlags; + /** Offset 0x578 - RIP. */ + uint64_t u64RIP; + /** Offset 0x580-0x5D7 - Reserved. */ + uint8_t u8Reserved7[0x5D8-0x580]; + /** Offset 0x5D8 - RSP. */ + uint64_t u64RSP; + /** Offset 0x5E0-0x5F7 - Reserved. */ + uint8_t u8Reserved8[0x5F8-0x5E0]; + /** Offset 0x5F8 - RAX. */ + uint64_t u64RAX; + /** Offset 0x600 - STAR. */ + uint64_t u64STAR; + /** Offset 0x608 - LSTAR. */ + uint64_t u64LSTAR; + /** Offset 0x610 - CSTAR. */ + uint64_t u64CSTAR; + /** Offset 0x618 - SFMASK. */ + uint64_t u64SFMASK; + /** Offset 0x620 - KernelGSBase. */ + uint64_t u64KernelGSBase; + /** Offset 0x628 - SYSENTER_CS. */ + uint64_t u64SysEnterCS; + /** Offset 0x630 - SYSENTER_ESP. */ + uint64_t u64SysEnterESP; + /** Offset 0x638 - SYSENTER_EIP. */ + uint64_t u64SysEnterEIP; + /** Offset 0x640 - CR2. */ + uint64_t u64CR2; + /** Offset 0x648-0x667 - Reserved. */ + uint8_t u8Reserved9[0x668-0x648]; + /** Offset 0x668 - G_PAT. */ + uint64_t u64GPAT; + /** Offset 0x670 - DBGCTL. */ + uint64_t u64DBGCTL; + /** Offset 0x678 - BR_FROM. */ + uint64_t u64BR_FROM; + /** Offset 0x680 - BR_TO. */ + uint64_t u64BR_TO; + /** Offset 0x688 - LASTEXCPFROM. */ + uint64_t u64LASTEXCPFROM; + /** Offset 0x690 - LASTEXCPTO. */ + uint64_t u64LASTEXCPTO; + } guest; + + /** Offset 0x698-0xFFF- Reserved. */ + uint8_t u8Reserved10[0x1000-0x698]; +} SVMVMCB; +#pragma pack() +/** Pointer to the SVMVMCB structure. */ +typedef SVMVMCB *PSVMVMCB; +AssertCompileMemberOffset(SVMVMCB, ctrl.u16InterceptRdCRx, 0x000); +AssertCompileMemberOffset(SVMVMCB, ctrl.u16PauseFilterCount, 0x03e); +AssertCompileMemberOffset(SVMVMCB, ctrl.TLBCtrl, 0x058); +AssertCompileMemberOffset(SVMVMCB, ctrl.ExitIntInfo, 0x088); +AssertCompileMemberOffset(SVMVMCB, ctrl.EventInject, 0x0A8); +AssertCompileMemberOffset(SVMVMCB, ctrl.abInstr, 0x0D1); +AssertCompileMemberOffset(SVMVMCB, ctrl.AvicBackingPagePtr, 0x0E0); +AssertCompileMemberOffset(SVMVMCB, ctrl.AvicLogicalTablePtr, 0x0F0); +AssertCompileMemberOffset(SVMVMCB, ctrl.AvicPhysicalTablePtr, 0x0F8); +AssertCompileMemberOffset(SVMVMCB, guest, 0x400); +AssertCompileMemberOffset(SVMVMCB, guest.ES, 0x400); +AssertCompileMemberOffset(SVMVMCB, guest.TR, 0x490); +AssertCompileMemberOffset(SVMVMCB, guest.u64EFER, 0x4D0); +AssertCompileMemberOffset(SVMVMCB, guest.u64CR4, 0x548); +AssertCompileMemberOffset(SVMVMCB, guest.u64RIP, 0x578); +AssertCompileMemberOffset(SVMVMCB, guest.u64RSP, 0x5D8); +AssertCompileMemberOffset(SVMVMCB, guest.u64CR2, 0x640); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved4, 0x4A0); +AssertCompileMemberOffset(SVMVMCB, guest.u8CPL, 0x4CB); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved6, 0x4D8); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved7, 0x580); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved9, 0x648); +AssertCompileMemberOffset(SVMVMCB, guest.u64GPAT, 0x668); +AssertCompileMemberOffset(SVMVMCB, guest.u64LASTEXCPTO, 0x690); +AssertCompileMemberOffset(SVMVMCB, u8Reserved10, 0x698); +AssertCompileSize(SVMVMCB, 0x1000); + +#ifdef IN_RING0 +VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); +#endif /* IN_RING0 */ + +/** @} */ + +#endif + diff --git a/include/VBox/vmm/hm_vmx.h b/include/VBox/vmm/hm_vmx.h new file mode 100644 index 00000000..a84b01ca --- /dev/null +++ b/include/VBox/vmm/hm_vmx.h @@ -0,0 +1,2343 @@ +/** @file + * HM - VMX Structures and Definitions. (VMM) + */ + +/* + * 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; + * 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 ___VBox_vmm_vmx_h +#define ___VBox_vmm_vmx_h + +#include +#include +#include +#include + +/* In Visual C++ versions prior to 2012, the vmx intrinsics are only available + when targeting AMD64. */ +#if RT_INLINE_ASM_USES_INTRIN >= 16 && defined(RT_ARCH_AMD64) +# include +/* We always want them as intrinsics, no functions. */ +# pragma intrinsic(__vmx_on) +# pragma intrinsic(__vmx_off) +# pragma intrinsic(__vmx_vmclear) +# pragma intrinsic(__vmx_vmptrld) +# pragma intrinsic(__vmx_vmread) +# pragma intrinsic(__vmx_vmwrite) +# define VMX_USE_MSC_INTRINSICS 1 +#else +# define VMX_USE_MSC_INTRINSICS 0 +#endif + + +/** @defgroup grp_vmx vmx Types and Definitions + * @ingroup grp_hm + * @{ + */ + +/** @def HMVMXCPU_GST_SET_UPDATED + * Sets a guest-state-updated flag. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlag The flag to set. + */ +#define HMVMXCPU_GST_SET_UPDATED(pVCpu, fFlag) (ASMAtomicUoOrU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlag))) + +/** @def HMVMXCPU_GST_IS_SET + * Checks if all the flags in the specified guest-state-updated set is pending. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlag The flag to check. + */ +#define HMVMXCPU_GST_IS_SET(pVCpu, fFlag) ((ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlag)) == (fFlag)) + +/** @def HMVMXCPU_GST_IS_UPDATED + * Checks if one or more of the flags in the specified guest-state-updated set + * is updated. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlags The flags to check for. + */ +#define HMVMXCPU_GST_IS_UPDATED(pVCpu, fFlags) RT_BOOL(ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlags)) + +/** @def HMVMXCPU_GST_RESET_TO + * Resets the guest-state-updated flags to the specified value. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlags The new value. + */ +#define HMVMXCPU_GST_RESET_TO(pVCpu, fFlags) (ASMAtomicUoWriteU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlags))) + +/** @def HMVMXCPU_GST_VALUE + * Returns the current guest-state-updated flags value. + * + * @param pVCpu Pointer to the VMCPU. + */ +#define HMVMXCPU_GST_VALUE(pVCpu) (ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState)) + +/** @name Host-state restoration flags. + * @{ + */ +/* If you change these values don't forget to update the assembly defines as well! */ +#define VMX_RESTORE_HOST_SEL_DS RT_BIT(0) +#define VMX_RESTORE_HOST_SEL_ES RT_BIT(1) +#define VMX_RESTORE_HOST_SEL_FS RT_BIT(2) +#define VMX_RESTORE_HOST_SEL_GS RT_BIT(3) +#define VMX_RESTORE_HOST_SEL_TR RT_BIT(4) +#define VMX_RESTORE_HOST_GDTR RT_BIT(5) +#define VMX_RESTORE_HOST_IDTR RT_BIT(6) +#define VMX_RESTORE_HOST_REQUIRED RT_BIT(7) +/** @} */ + +/** + * Host-state restoration structure. + * This holds host-state fields that require manual restoration. + * Assembly version found in hm_vmx.mac (should be automatically verified). + */ +typedef struct VMXRESTOREHOST +{ + RTSEL uHostSelDS; /* 0x00 */ + RTSEL uHostSelES; /* 0x02 */ + RTSEL uHostSelFS; /* 0x04 */ + RTSEL uHostSelGS; /* 0x06 */ + RTSEL uHostSelTR; /* 0x08 */ + uint8_t abPadding0[4]; + X86XDTR64 HostGdtr; /**< 0x0e - should be aligned by it's 64-bit member. */ + uint8_t abPadding1[6]; + X86XDTR64 HostIdtr; /**< 0x1e - should be aligned by it's 64-bit member. */ + uint64_t uHostFSBase; /* 0x28 */ + uint64_t uHostGSBase; /* 0x30 */ +} VMXRESTOREHOST; +/** Pointer to VMXRESTOREHOST. */ +typedef VMXRESTOREHOST *PVMXRESTOREHOST; +AssertCompileSize(X86XDTR64, 10); +AssertCompileMemberOffset(VMXRESTOREHOST, HostGdtr.uAddr, 16); +AssertCompileMemberOffset(VMXRESTOREHOST, HostIdtr.uAddr, 32); +AssertCompileMemberOffset(VMXRESTOREHOST, uHostFSBase, 40); +AssertCompileSize(VMXRESTOREHOST, 56); + +/** @name VMX HM-error codes for VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO. + * UFC = Unsupported Feature Combination. + * @{ + */ +/** Unsupported pin-based VM-execution controls combo. */ +#define VMX_UFC_CTRL_PIN_EXEC 0 +/** Unsupported processor-based VM-execution controls combo. */ +#define VMX_UFC_CTRL_PROC_EXEC 1 +/** Unsupported pin-based VM-execution controls combo. */ +#define VMX_UFC_CTRL_PROC_MOV_DRX_EXIT 2 +/** Unsupported VM-entry controls combo. */ +#define VMX_UFC_CTRL_ENTRY 3 +/** Unsupported VM-exit controls combo. */ +#define VMX_UFC_CTRL_EXIT 4 +/** MSR storage capacity of the VMCS autoload/store area is not sufficient + * for storing host MSRs. */ +#define VMX_UFC_INSUFFICIENT_HOST_MSR_STORAGE 5 +/** MSR storage capacity of the VMCS autoload/store area is not sufficient + * for storing guest MSRs. */ +#define VMX_UFC_INSUFFICIENT_GUEST_MSR_STORAGE 6 +/** Invalid VMCS size. */ +#define VMX_UFC_INVALID_VMCS_SIZE 7 +/** @} */ + +/** @name VMX HM-error codes for VERR_VMX_INVALID_GUEST_STATE. + * IGS = Invalid Guest State. + * @{ + */ +/** An error occurred while checking invalid-guest-state. */ +#define VMX_IGS_ERROR 0 +/** The invalid guest-state checks did not find any reason why. */ +#define VMX_IGS_REASON_NOT_FOUND 1 +/** CR0 fixed1 bits invalid. */ +#define VMX_IGS_CR0_FIXED1 2 +/** CR0 fixed0 bits invalid. */ +#define VMX_IGS_CR0_FIXED0 3 +/** CR0.PE and CR0.PE invalid VT-x/host combination. */ +#define VMX_IGS_CR0_PG_PE_COMBO 4 +/** CR4 fixed1 bits invalid. */ +#define VMX_IGS_CR4_FIXED1 5 +/** CR4 fixed0 bits invalid. */ +#define VMX_IGS_CR4_FIXED0 6 +/** Reserved bits in VMCS' DEBUGCTL MSR field not set to 0 when + * VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG is used. */ +#define VMX_IGS_DEBUGCTL_MSR_RESERVED 7 +/** CR0.PG not set for long-mode when not using unrestricted guest. */ +#define VMX_IGS_CR0_PG_LONGMODE 8 +/** CR4.PAE not set for long-mode guest when not using unrestricted guest. */ +#define VMX_IGS_CR4_PAE_LONGMODE 9 +/** CR4.PCIDE set for 32-bit guest. */ +#define VMX_IGS_CR4_PCIDE 10 +/** VMCS' DR7 reserved bits not set to 0. */ +#define VMX_IGS_DR7_RESERVED 11 +/** VMCS' PERF_GLOBAL MSR reserved bits not set to 0. */ +#define VMX_IGS_PERF_GLOBAL_MSR_RESERVED 12 +/** VMCS' EFER MSR reserved bits not set to 0. */ +#define VMX_IGS_EFER_MSR_RESERVED 13 +/** VMCS' EFER MSR.LMA does not match the IA32e mode guest control. */ +#define VMX_IGS_EFER_LMA_GUEST_MODE_MISMATCH 14 +/** VMCS' EFER MSR.LMA does not match CR0.PG of the guest when not using + * unrestricted guest. */ +#define VMX_IGS_EFER_LMA_PG_MISMATCH 15 +/** CS.Attr.P bit invalid. */ +#define VMX_IGS_CS_ATTR_P_INVALID 16 +/** CS.Attr reserved bits not set to 0. */ +#define VMX_IGS_CS_ATTR_RESERVED 17 +/** CS.Attr.G bit invalid. */ +#define VMX_IGS_CS_ATTR_G_INVALID 18 +/** CS is unusable. */ +#define VMX_IGS_CS_ATTR_UNUSABLE 19 +/** CS and SS DPL unequal. */ +#define VMX_IGS_CS_SS_ATTR_DPL_UNEQUAL 20 +/** CS and SS DPL mismatch. */ +#define VMX_IGS_CS_SS_ATTR_DPL_MISMATCH 21 +/** CS Attr.Type invalid. */ +#define VMX_IGS_CS_ATTR_TYPE_INVALID 22 +/** CS and SS RPL unequal. */ +#define VMX_IGS_SS_CS_RPL_UNEQUAL 23 +/** SS.Attr.DPL and SS RPL unequal. */ +#define VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL 24 +/** SS.Attr.DPL invalid for segment type. */ +#define VMX_IGS_SS_ATTR_DPL_INVALID 25 +/** SS.Attr.Type invalid. */ +#define VMX_IGS_SS_ATTR_TYPE_INVALID 26 +/** SS.Attr.P bit invalid. */ +#define VMX_IGS_SS_ATTR_P_INVALID 27 +/** SS.Attr reserved bits not set to 0. */ +#define VMX_IGS_SS_ATTR_RESERVED 28 +/** SS.Attr.G bit invalid. */ +#define VMX_IGS_SS_ATTR_G_INVALID 29 +/** DS.Attr.A bit invalid. */ +#define VMX_IGS_DS_ATTR_A_INVALID 30 +/** DS.Attr.P bit invalid. */ +#define VMX_IGS_DS_ATTR_P_INVALID 31 +/** DS.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL 32 +/** DS.Attr reserved bits not set to 0. */ +#define VMX_IGS_DS_ATTR_RESERVED 33 +/** DS.Attr.G bit invalid. */ +#define VMX_IGS_DS_ATTR_G_INVALID 34 +/** DS.Attr.Type invalid. */ +#define VMX_IGS_DS_ATTR_TYPE_INVALID 35 +/** ES.Attr.A bit invalid. */ +#define VMX_IGS_ES_ATTR_A_INVALID 36 +/** ES.Attr.P bit invalid. */ +#define VMX_IGS_ES_ATTR_P_INVALID 37 +/** ES.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_ES_ATTR_DPL_RPL_UNEQUAL 38 +/** ES.Attr reserved bits not set to 0. */ +#define VMX_IGS_ES_ATTR_RESERVED 39 +/** ES.Attr.G bit invalid. */ +#define VMX_IGS_ES_ATTR_G_INVALID 40 +/** ES.Attr.Type invalid. */ +#define VMX_IGS_ES_ATTR_TYPE_INVALID 41 +/** FS.Attr.A bit invalid. */ +#define VMX_IGS_FS_ATTR_A_INVALID 42 +/** FS.Attr.P bit invalid. */ +#define VMX_IGS_FS_ATTR_P_INVALID 43 +/** FS.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL 44 +/** FS.Attr reserved bits not set to 0. */ +#define VMX_IGS_FS_ATTR_RESERVED 45 +/** FS.Attr.G bit invalid. */ +#define VMX_IGS_FS_ATTR_G_INVALID 46 +/** FS.Attr.Type invalid. */ +#define VMX_IGS_FS_ATTR_TYPE_INVALID 47 +/** GS.Attr.A bit invalid. */ +#define VMX_IGS_GS_ATTR_A_INVALID 48 +/** GS.Attr.P bit invalid. */ +#define VMX_IGS_GS_ATTR_P_INVALID 49 +/** GS.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL 50 +/** GS.Attr reserved bits not set to 0. */ +#define VMX_IGS_GS_ATTR_RESERVED 51 +/** GS.Attr.G bit invalid. */ +#define VMX_IGS_GS_ATTR_G_INVALID 52 +/** GS.Attr.Type invalid. */ +#define VMX_IGS_GS_ATTR_TYPE_INVALID 53 +/** V86 mode CS.Base invalid. */ +#define VMX_IGS_V86_CS_BASE_INVALID 54 +/** V86 mode CS.Limit invalid. */ +#define VMX_IGS_V86_CS_LIMIT_INVALID 55 +/** V86 mode CS.Attr invalid. */ +#define VMX_IGS_V86_CS_ATTR_INVALID 56 +/** V86 mode SS.Base invalid. */ +#define VMX_IGS_V86_SS_BASE_INVALID 57 +/** V86 mode SS.Limit invalid. */ +#define VMX_IGS_V86_SS_LIMIT_INVALID 59 +/** V86 mode SS.Attr invalid. */ +#define VMX_IGS_V86_SS_ATTR_INVALID 59 +/** V86 mode DS.Base invalid. */ +#define VMX_IGS_V86_DS_BASE_INVALID 60 +/** V86 mode DS.Limit invalid. */ +#define VMX_IGS_V86_DS_LIMIT_INVALID 61 +/** V86 mode DS.Attr invalid. */ +#define VMX_IGS_V86_DS_ATTR_INVALID 62 +/** V86 mode ES.Base invalid. */ +#define VMX_IGS_V86_ES_BASE_INVALID 63 +/** V86 mode ES.Limit invalid. */ +#define VMX_IGS_V86_ES_LIMIT_INVALID 64 +/** V86 mode ES.Attr invalid. */ +#define VMX_IGS_V86_ES_ATTR_INVALID 65 +/** V86 mode FS.Base invalid. */ +#define VMX_IGS_V86_FS_BASE_INVALID 66 +/** V86 mode FS.Limit invalid. */ +#define VMX_IGS_V86_FS_LIMIT_INVALID 67 +/** V86 mode FS.Attr invalid. */ +#define VMX_IGS_V86_FS_ATTR_INVALID 68 +/** V86 mode GS.Base invalid. */ +#define VMX_IGS_V86_GS_BASE_INVALID 69 +/** V86 mode GS.Limit invalid. */ +#define VMX_IGS_V86_GS_LIMIT_INVALID 70 +/** V86 mode GS.Attr invalid. */ +#define VMX_IGS_V86_GS_ATTR_INVALID 71 +/** Longmode CS.Base invalid. */ +#define VMX_IGS_LONGMODE_CS_BASE_INVALID 72 +/** Longmode SS.Base invalid. */ +#define VMX_IGS_LONGMODE_SS_BASE_INVALID 73 +/** Longmode DS.Base invalid. */ +#define VMX_IGS_LONGMODE_DS_BASE_INVALID 74 +/** Longmode ES.Base invalid. */ +#define VMX_IGS_LONGMODE_ES_BASE_INVALID 75 +/** SYSENTER ESP is not canonical. */ +#define VMX_IGS_SYSENTER_ESP_NOT_CANONICAL 76 +/** SYSENTER EIP is not canonical. */ +#define VMX_IGS_SYSENTER_EIP_NOT_CANONICAL 77 +/** PAT MSR invalid. */ +#define VMX_IGS_PAT_MSR_INVALID 78 +/** PAT MSR reserved bits not set to 0. */ +#define VMX_IGS_PAT_MSR_RESERVED 79 +/** GDTR.Base is not canonical. */ +#define VMX_IGS_GDTR_BASE_NOT_CANONICAL 80 +/** IDTR.Base is not canonical. */ +#define VMX_IGS_IDTR_BASE_NOT_CANONICAL 81 +/** GDTR.Limit invalid. */ +#define VMX_IGS_GDTR_LIMIT_INVALID 82 +/** IDTR.Limit invalid. */ +#define VMX_IGS_IDTR_LIMIT_INVALID 83 +/** Longmode RIP is invalid. */ +#define VMX_IGS_LONGMODE_RIP_INVALID 84 +/** RFLAGS reserved bits not set to 0. */ +#define VMX_IGS_RFLAGS_RESERVED 85 +/** RFLAGS RA1 reserved bits not set to 1. */ +#define VMX_IGS_RFLAGS_RESERVED1 86 +/** RFLAGS.VM (V86 mode) invalid. */ +#define VMX_IGS_RFLAGS_VM_INVALID 87 +/** RFLAGS.IF invalid. */ +#define VMX_IGS_RFLAGS_IF_INVALID 88 +/** Activity state invalid. */ +#define VMX_IGS_ACTIVITY_STATE_INVALID 89 +/** Activity state HLT invalid when SS.Attr.DPL is not zero. */ +#define VMX_IGS_ACTIVITY_STATE_HLT_INVALID 90 +/** Activity state ACTIVE invalid when block-by-STI or MOV SS. */ +#define VMX_IGS_ACTIVITY_STATE_ACTIVE_INVALID 91 +/** Activity state SIPI WAIT invalid. */ +#define VMX_IGS_ACTIVITY_STATE_SIPI_WAIT_INVALID 92 +/** Interruptibility state reserved bits not set to 0. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_RESERVED 93 +/** Interruptibility state cannot be block-by-STI -and- MOV SS. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_MOVSS_INVALID 94 +/** Interruptibility state block-by-STI invalid for EFLAGS. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_EFL_INVALID 95 +/** Interruptibility state invalid while trying to deliver external + * interrupt. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_EXT_INT_INVALID 96 +/** Interruptibility state block-by-MOVSS invalid while trying to deliver an + * NMI. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_MOVSS_INVALID 97 +/** Interruptibility state block-by-SMI invalid when CPU is not in SMM. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_INVALID 98 +/** Interruptibility state block-by-SMI invalid when trying to enter SMM. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_SMM_INVALID 99 +/** Interruptibilty state block-by-STI (maybe) invalid when trying to deliver + * an NMI. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_INVALID 100 +/** Interruptibility state block-by-NMI invalid when virtual-NMIs control is + * active. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_NMI_INVALID 101 +/** Pending debug exceptions reserved bits not set to 0. */ +#define VMX_IGS_PENDING_DEBUG_RESERVED 102 +/** Longmode pending debug exceptions reserved bits not set to 0. */ +#define VMX_IGS_LONGMODE_PENDING_DEBUG_RESERVED 103 +/** Pending debug exceptions.BS bit is not set when it should be. */ +#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_SET 104 +/** Pending debug exceptions.BS bit is not clear when it should be. */ +#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_CLEAR 105 +/** VMCS link pointer reserved bits not set to 0. */ +#define VMX_IGS_VMCS_LINK_PTR_RESERVED 106 +/** TR cannot index into LDT, TI bit MBZ. */ +#define VMX_IGS_TR_TI_INVALID 107 +/** LDTR cannot index into LDT. TI bit MBZ. */ +#define VMX_IGS_LDTR_TI_INVALID 108 +/** TR.Base is not canonical. */ +#define VMX_IGS_TR_BASE_NOT_CANONICAL 109 +/** FS.Base is not canonical. */ +#define VMX_IGS_FS_BASE_NOT_CANONICAL 110 +/** GS.Base is not canonical. */ +#define VMX_IGS_GS_BASE_NOT_CANONICAL 111 +/** LDTR.Base is not canonical. */ +#define VMX_IGS_LDTR_BASE_NOT_CANONICAL 112 +/** TR is unusable. */ +#define VMX_IGS_TR_ATTR_UNUSABLE 113 +/** TR.Attr.S bit invalid. */ +#define VMX_IGS_TR_ATTR_S_INVALID 114 +/** TR is not present. */ +#define VMX_IGS_TR_ATTR_P_INVALID 115 +/** TR.Attr reserved bits not set to 0. */ +#define VMX_IGS_TR_ATTR_RESERVED 116 +/** TR.Attr.G bit invalid. */ +#define VMX_IGS_TR_ATTR_G_INVALID 117 +/** Longmode TR.Attr.Type invalid. */ +#define VMX_IGS_LONGMODE_TR_ATTR_TYPE_INVALID 118 +/** TR.Attr.Type invalid. */ +#define VMX_IGS_TR_ATTR_TYPE_INVALID 119 +/** CS.Attr.S invalid. */ +#define VMX_IGS_CS_ATTR_S_INVALID 120 +/** CS.Attr.DPL invalid. */ +#define VMX_IGS_CS_ATTR_DPL_INVALID 121 +/** PAE PDPTE reserved bits not set to 0. */ +#define VMX_IGS_PAE_PDPTE_RESERVED 123 +/** @} */ + +/** @name VMX VMCS-Read cache indices. + * @{ + */ +# define VMX_VMCS_GUEST_ES_BASE_CACHE_IDX 0 +# define VMX_VMCS_GUEST_CS_BASE_CACHE_IDX 1 +# define VMX_VMCS_GUEST_SS_BASE_CACHE_IDX 2 +# define VMX_VMCS_GUEST_DS_BASE_CACHE_IDX 3 +# define VMX_VMCS_GUEST_FS_BASE_CACHE_IDX 4 +# define VMX_VMCS_GUEST_GS_BASE_CACHE_IDX 5 +# define VMX_VMCS_GUEST_LDTR_BASE_CACHE_IDX 6 +# define VMX_VMCS_GUEST_TR_BASE_CACHE_IDX 7 +# define VMX_VMCS_GUEST_GDTR_BASE_CACHE_IDX 8 +# define VMX_VMCS_GUEST_IDTR_BASE_CACHE_IDX 9 +# define VMX_VMCS_GUEST_RSP_CACHE_IDX 10 +# define VMX_VMCS_GUEST_RIP_CACHE_IDX 11 +# define VMX_VMCS_GUEST_SYSENTER_ESP_CACHE_IDX 12 +# define VMX_VMCS_GUEST_SYSENTER_EIP_CACHE_IDX 13 +# define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX 14 +# define VMX_VMCS_MAX_CACHE_IDX (VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX + 1) +# define VMX_VMCS_GUEST_CR3_CACHE_IDX 15 +# define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX (VMX_VMCS_GUEST_CR3_CACHE_IDX + 1) +/** @} */ + +/** @name VMX EPT paging structures + * @{ + */ + +/** + * Number of page table entries in the EPT. (PDPTE/PDE/PTE) + */ +#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES + +/** + * EPT Page Directory Pointer Entry. Bit view. + * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC, + * this did cause trouble with one compiler/version). + */ +#pragma pack(1) +typedef struct EPTPML4EBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** Reserved (must be 0). */ + uint64_t u5Reserved : 5; + /** Available for software. */ + uint64_t u4Available : 4; + /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPML4EBITS; +#pragma pack() +AssertCompileSize(EPTPML4EBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK +/** The page shift to get the PML4 index. */ +#define EPT_PML4_SHIFT X86_PML4_SHIFT +/** The PML4 index mask (apply to a shifted page address). */ +#define EPT_PML4_MASK X86_PML4_MASK + +/** + * EPT PML4E. + */ +#pragma pack(1) +typedef union EPTPML4E +{ + /** Normal view. */ + EPTPML4EBITS n; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPML4E; +#pragma pack() +/** Pointer to a PML4 table entry. */ +typedef EPTPML4E *PEPTPML4E; +/** Pointer to a const PML4 table entry. */ +typedef const EPTPML4E *PCEPTPML4E; +AssertCompileSize(EPTPML4E, 8); + +/** + * EPT PML4 Table. + */ +#pragma pack(1) +typedef struct EPTPML4 +{ + EPTPML4E a[EPT_PG_ENTRIES]; +} EPTPML4; +#pragma pack() +/** Pointer to an EPT PML4 Table. */ +typedef EPTPML4 *PEPTPML4; +/** Pointer to a const EPT PML4 Table. */ +typedef const EPTPML4 *PCEPTPML4; + +/** + * EPT Page Directory Pointer Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPDPTEBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** Reserved (must be 0). */ + uint64_t u5Reserved : 5; + /** Available for software. */ + uint64_t u4Available : 4; + /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPDPTEBITS; +#pragma pack() +AssertCompileSize(EPTPDPTEBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK +/** The page shift to get the PDPT index. */ +#define EPT_PDPT_SHIFT X86_PDPT_SHIFT +/** The PDPT index mask (apply to a shifted page address). */ +#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64 + +/** + * EPT Page Directory Pointer. + */ +#pragma pack(1) +typedef union EPTPDPTE +{ + /** Normal view. */ + EPTPDPTEBITS n; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPDPTE; +#pragma pack() +/** Pointer to an EPT Page Directory Pointer Entry. */ +typedef EPTPDPTE *PEPTPDPTE; +/** Pointer to a const EPT Page Directory Pointer Entry. */ +typedef const EPTPDPTE *PCEPTPDPTE; +AssertCompileSize(EPTPDPTE, 8); + +/** + * EPT Page Directory Pointer Table. + */ +#pragma pack(1) +typedef struct EPTPDPT +{ + EPTPDPTE a[EPT_PG_ENTRIES]; +} EPTPDPT; +#pragma pack() +/** Pointer to an EPT Page Directory Pointer Table. */ +typedef EPTPDPT *PEPTPDPT; +/** Pointer to a const EPT Page Directory Pointer Table. */ +typedef const EPTPDPT *PCEPTPDPT; + + +/** + * EPT Page Directory Table Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPDEBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** Reserved (must be 0). */ + uint64_t u4Reserved : 4; + /** Big page (must be 0 here). */ + uint64_t u1Size : 1; + /** Available for software. */ + uint64_t u4Available : 4; + /** Physical address of page table. Restricted by maximum physical address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPDEBITS; +#pragma pack() +AssertCompileSize(EPTPDEBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK +/** The page shift to get the PD index. */ +#define EPT_PD_SHIFT X86_PD_PAE_SHIFT +/** The PD index mask (apply to a shifted page address). */ +#define EPT_PD_MASK X86_PD_PAE_MASK + +/** + * EPT 2MB Page Directory Table Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPDE2MBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** EPT Table Memory Type. MBZ for non-leaf nodes. */ + uint64_t u3EMT : 3; + /** Ignore PAT memory type */ + uint64_t u1IgnorePAT : 1; + /** Big page (must be 1 here). */ + uint64_t u1Size : 1; + /** Available for software. */ + uint64_t u4Available : 4; + /** Reserved (must be 0). */ + uint64_t u9Reserved : 9; + /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */ + uint64_t u31PhysAddr : 31; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPDE2MBITS; +#pragma pack() +AssertCompileSize(EPTPDE2MBITS, 8); + +/** Bits 21-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK + +/** + * EPT Page Directory Table Entry. + */ +#pragma pack(1) +typedef union EPTPDE +{ + /** Normal view. */ + EPTPDEBITS n; + /** 2MB view (big). */ + EPTPDE2MBITS b; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPDE; +#pragma pack() +/** Pointer to an EPT Page Directory Table Entry. */ +typedef EPTPDE *PEPTPDE; +/** Pointer to a const EPT Page Directory Table Entry. */ +typedef const EPTPDE *PCEPTPDE; +AssertCompileSize(EPTPDE, 8); + +/** + * EPT Page Directory Table. + */ +#pragma pack(1) +typedef struct EPTPD +{ + EPTPDE a[EPT_PG_ENTRIES]; +} EPTPD; +#pragma pack() +/** Pointer to an EPT Page Directory Table. */ +typedef EPTPD *PEPTPD; +/** Pointer to a const EPT Page Directory Table. */ +typedef const EPTPD *PCEPTPD; + + +/** + * EPT Page Table Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPTEBITS +{ + /** 0 - Present bit. + * @remark This is a convenience "misnomer". The bit actually indicates + * read access and the CPU will consider an entry with any of the + * first three bits set as present. Since all our valid entries + * will have this bit set, it can be used as a present indicator + * and allow some code sharing. */ + uint64_t u1Present : 1; + /** 1 - Writable bit. */ + uint64_t u1Write : 1; + /** 2 - Executable bit. */ + uint64_t u1Execute : 1; + /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */ + uint64_t u3EMT : 3; + /** 6 - Ignore PAT memory type */ + uint64_t u1IgnorePAT : 1; + /** 11:7 - Available for software. */ + uint64_t u5Available : 5; + /** 51:12 - Physical address of page. Restricted by maximum physical + * address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** 63:52 - Available for software. */ + uint64_t u12Available : 12; +} EPTPTEBITS; +#pragma pack() +AssertCompileSize(EPTPTEBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK +/** The page shift to get the EPT PTE index. */ +#define EPT_PT_SHIFT X86_PT_PAE_SHIFT +/** The EPT PT index mask (apply to a shifted page address). */ +#define EPT_PT_MASK X86_PT_PAE_MASK + +/** + * EPT Page Table Entry. + */ +#pragma pack(1) +typedef union EPTPTE +{ + /** Normal view. */ + EPTPTEBITS n; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPTE; +#pragma pack() +/** Pointer to an EPT Page Directory Table Entry. */ +typedef EPTPTE *PEPTPTE; +/** Pointer to a const EPT Page Directory Table Entry. */ +typedef const EPTPTE *PCEPTPTE; +AssertCompileSize(EPTPTE, 8); + +/** + * EPT Page Table. + */ +#pragma pack(1) +typedef struct EPTPT +{ + EPTPTE a[EPT_PG_ENTRIES]; +} EPTPT; +#pragma pack() +/** Pointer to an extended page table. */ +typedef EPTPT *PEPTPT; +/** Pointer to a const extended table. */ +typedef const EPTPT *PCEPTPT; + +/** + * VPID flush types. + */ +typedef enum +{ + /** Invalidate a specific page. */ + VMX_FLUSH_VPID_INDIV_ADDR = 0, + /** Invalidate one context (specific VPID). */ + VMX_FLUSH_VPID_SINGLE_CONTEXT = 1, + /** Invalidate all contexts (all VPIDs). */ + VMX_FLUSH_VPID_ALL_CONTEXTS = 2, + /** Invalidate a single VPID context retaining global mappings. */ + VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3, + /** Unsupported by VirtualBox. */ + VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad, + /** Unsupported by CPU. */ + VMX_FLUSH_VPID_NONE = 0xb00, + /** 32bit hackishness. */ + VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff +} VMX_FLUSH_VPID; + +/** + * EPT flush types. + */ +typedef enum +{ + /** Invalidate one context (specific EPT). */ + VMX_FLUSH_EPT_SINGLE_CONTEXT = 1, + /* Invalidate all contexts (all EPTs) */ + VMX_FLUSH_EPT_ALL_CONTEXTS = 2, + /** Unsupported by VirtualBox. */ + VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad, + /** Unsupported by CPU. */ + VMX_FLUSH_EPT_NONE = 0xb00, + /** 32bit hackishness. */ + VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff +} VMX_FLUSH_EPT; +/** @} */ + +/** @name MSR autoload/store elements + * @{ + */ +#pragma pack(1) +typedef struct +{ + uint32_t u32Msr; + uint32_t u32Reserved; + uint64_t u64Value; +} VMXAUTOMSR; +#pragma pack() +/** Pointer to an MSR load/store element. */ +typedef VMXAUTOMSR *PVMXAUTOMSR; +/** Pointer to a const MSR load/store element. */ +typedef const VMXAUTOMSR *PCVMXAUTOMSR; +/** @} */ + +/** @name VMX-capability qword + * @{ + */ +#pragma pack(1) +typedef union +{ + struct + { + /** Bits set here -must- be set in the correpsonding VM-execution controls. */ + uint32_t disallowed0; + /** Bits cleared here -must- be cleared in the corresponding VM-execution + * controls. */ + uint32_t allowed1; + } n; + uint64_t u; +} VMX_CAPABILITY; +#pragma pack() +/** @} */ + +/** @name VMX MSRs. + * @{ + */ +typedef struct VMXMSRS +{ + uint64_t u64FeatureCtrl; + uint64_t u64BasicInfo; + VMX_CAPABILITY VmxPinCtls; + VMX_CAPABILITY VmxProcCtls; + VMX_CAPABILITY VmxProcCtls2; + VMX_CAPABILITY VmxExit; + VMX_CAPABILITY VmxEntry; + uint64_t u64Misc; + uint64_t u64Cr0Fixed0; + uint64_t u64Cr0Fixed1; + uint64_t u64Cr4Fixed0; + uint64_t u64Cr4Fixed1; + uint64_t u64VmcsEnum; + uint64_t u64Vmfunc; + uint64_t u64EptVpidCaps; +} VMXMSRS; +/** Pointer to a VMXMSRS struct. */ +typedef VMXMSRS *PVMXMSRS; +/** @} */ + +/** @name VMX EFLAGS reserved bits. + * @{ + */ +/** And-mask for setting reserved bits to zero */ +#define VMX_EFLAGS_RESERVED_0 (~0xffc08028) +/** Or-mask for setting reserved bits to 1 */ +#define VMX_EFLAGS_RESERVED_1 0x00000002 +/** @} */ + +/** @name VMX Basic Exit Reasons. + * @{ + */ +/** -1 Invalid exit code */ +#define VMX_EXIT_INVALID -1 +/** 0 Exception or non-maskable interrupt (NMI). */ +#define VMX_EXIT_XCPT_OR_NMI 0 +/** 1 External interrupt. */ +#define VMX_EXIT_EXT_INT 1 +/** 2 Triple fault. */ +#define VMX_EXIT_TRIPLE_FAULT 2 +/** 3 INIT signal. */ +#define VMX_EXIT_INIT_SIGNAL 3 +/** 4 Start-up IPI (SIPI). */ +#define VMX_EXIT_SIPI 4 +/** 5 I/O system-management interrupt (SMI). */ +#define VMX_EXIT_IO_SMI 5 +/** 6 Other SMI. */ +#define VMX_EXIT_SMI 6 +/** 7 Interrupt window exiting. */ +#define VMX_EXIT_INT_WINDOW 7 +/** 8 NMI window exiting. */ +#define VMX_EXIT_NMI_WINDOW 8 +/** 9 Task switch. */ +#define VMX_EXIT_TASK_SWITCH 9 +/** 10 Guest software attempted to execute CPUID. */ +#define VMX_EXIT_CPUID 10 +/** 10 Guest software attempted to execute GETSEC. */ +#define VMX_EXIT_GETSEC 11 +/** 12 Guest software attempted to execute HLT. */ +#define VMX_EXIT_HLT 12 +/** 13 Guest software attempted to execute INVD. */ +#define VMX_EXIT_INVD 13 +/** 14 Guest software attempted to execute INVLPG. */ +#define VMX_EXIT_INVLPG 14 +/** 15 Guest software attempted to execute RDPMC. */ +#define VMX_EXIT_RDPMC 15 +/** 16 Guest software attempted to execute RDTSC. */ +#define VMX_EXIT_RDTSC 16 +/** 17 Guest software attempted to execute RSM in SMM. */ +#define VMX_EXIT_RSM 17 +/** 18 Guest software executed VMCALL. */ +#define VMX_EXIT_VMCALL 18 +/** 19 Guest software executed VMCLEAR. */ +#define VMX_EXIT_VMCLEAR 19 +/** 20 Guest software executed VMLAUNCH. */ +#define VMX_EXIT_VMLAUNCH 20 +/** 21 Guest software executed VMPTRLD. */ +#define VMX_EXIT_VMPTRLD 21 +/** 22 Guest software executed VMPTRST. */ +#define VMX_EXIT_VMPTRST 22 +/** 23 Guest software executed VMREAD. */ +#define VMX_EXIT_VMREAD 23 +/** 24 Guest software executed VMRESUME. */ +#define VMX_EXIT_VMRESUME 24 +/** 25 Guest software executed VMWRITE. */ +#define VMX_EXIT_VMWRITE 25 +/** 26 Guest software executed VMXOFF. */ +#define VMX_EXIT_VMXOFF 26 +/** 27 Guest software executed VMXON. */ +#define VMX_EXIT_VMXON 27 +/** 28 Control-register accesses. */ +#define VMX_EXIT_MOV_CRX 28 +/** 29 Debug-register accesses. */ +#define VMX_EXIT_MOV_DRX 29 +/** 30 I/O instruction. */ +#define VMX_EXIT_IO_INSTR 30 +/** 31 RDMSR. Guest software attempted to execute RDMSR. */ +#define VMX_EXIT_RDMSR 31 +/** 32 WRMSR. Guest software attempted to execute WRMSR. */ +#define VMX_EXIT_WRMSR 32 +/** 33 VM-entry failure due to invalid guest state. */ +#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33 +/** 34 VM-entry failure due to MSR loading. */ +#define VMX_EXIT_ERR_MSR_LOAD 34 +/** 36 Guest software executed MWAIT. */ +#define VMX_EXIT_MWAIT 36 +/** 37 VM exit due to monitor trap flag. */ +#define VMX_EXIT_MTF 37 +/** 39 Guest software attempted to execute MONITOR. */ +#define VMX_EXIT_MONITOR 39 +/** 40 Guest software attempted to execute PAUSE. */ +#define VMX_EXIT_PAUSE 40 +/** 41 VM-entry failure due to machine-check. */ +#define VMX_EXIT_ERR_MACHINE_CHECK 41 +/** 43 TPR below threshold. Guest software executed MOV to CR8. */ +#define VMX_EXIT_TPR_BELOW_THRESHOLD 43 +/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */ +#define VMX_EXIT_APIC_ACCESS 44 +/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */ +#define VMX_EXIT_XDTR_ACCESS 46 +/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */ +#define VMX_EXIT_TR_ACCESS 47 +/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */ +#define VMX_EXIT_EPT_VIOLATION 48 +/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */ +#define VMX_EXIT_EPT_MISCONFIG 49 +/** 50 INVEPT. Guest software attempted to execute INVEPT. */ +#define VMX_EXIT_INVEPT 50 +/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */ +#define VMX_EXIT_RDTSCP 51 +/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */ +#define VMX_EXIT_PREEMPT_TIMER 52 +/** 53 INVVPID. Guest software attempted to execute INVVPID. */ +#define VMX_EXIT_INVVPID 53 +/** 54 WBINVD. Guest software attempted to execute WBINVD. */ +#define VMX_EXIT_WBINVD 54 +/** 55 XSETBV. Guest software attempted to execute XSETBV. */ +#define VMX_EXIT_XSETBV 55 +/** 57 RDRAND. Guest software attempted to execute RDRAND. */ +#define VMX_EXIT_RDRAND 57 +/** 58 INVPCID. Guest software attempted to execute INVPCID. */ +#define VMX_EXIT_INVPCID 58 +/** 59 VMFUNC. Guest software attempted to execute VMFUNC. */ +#define VMX_EXIT_VMFUNC 59 +/** The maximum exit value (inclusive). */ +#define VMX_EXIT_MAX (VMX_EXIT_VMFUNC) +/** @} */ + + +/** @name VM Instruction Errors + * @{ + */ +/** VMCALL executed in VMX root operation. */ +#define VMX_ERROR_VMCALL 1 +/** VMCLEAR with invalid physical address. */ +#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2 +/** VMCLEAR with VMXON pointer. */ +#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3 +/** VMLAUNCH with non-clear VMCS. */ +#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4 +/** VMRESUME with non-launched VMCS. */ +#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5 +/** VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */ +#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6 +/** VM-entry with invalid control field(s). */ +#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7 +/** VM-entry with invalid host-state field(s). */ +#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8 +/** VMPTRLD with invalid physical address. */ +#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9 +/** VMPTRLD with VMXON pointer. */ +#define VMX_ERROR_VMPTRLD_VMXON_PTR 10 +/** VMPTRLD with incorrect VMCS revision identifier. */ +#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11 +/** VMREAD/VMWRITE from/to unsupported VMCS component. */ +#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12 +#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT +/** VMWRITE to read-only VMCS component. */ +#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13 +/** VMXON executed in VMX root operation. */ +#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15 +/** VM entry with invalid executive-VMCS pointer. */ +#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16 +/** VM entry with non-launched executive VMCS. */ +#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17 +/** VM entry with executive-VMCS pointer not VMXON pointer. */ +#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18 +/** VMCALL with non-clear VMCS. */ +#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19 +/** VMCALL with invalid VM-exit control fields. */ +#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20 +/** VMCALL with incorrect MSEG revision identifier. */ +#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22 +/** VMXOFF under dual-monitor treatment of SMIs and SMM. */ +#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23 +/** VMCALL with invalid SMM-monitor features. */ +#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24 +/** VM entry with invalid VM-execution control fields in executive VMCS. */ +#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25 +/** VM entry with events blocked by MOV SS. */ +#define VMX_ERROR_VMENTRY_MOV_SS 26 +/** Invalid operand to INVEPT/INVVPID. */ +#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28 + +/** @} */ + + +/** @name VMX MSRs - Basic VMX information. + * @{ + */ +/** VMCS revision identifier used by the processor. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) ((a) & 0x7FFFFFFF) +/** Size of the VMCS. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0x1FFF) +/** Width of physical address used for the VMCS. + * 0 -> limited to the available amount of physical ram + * 1 -> within the first 4 GB + */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1) +/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1) +/** Memory type that must be used for the VMCS. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF) +/** Whether the processor provides additional information for exits due to INS/OUTS. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(a) RT_BOOL((a) & RT_BIT_64(54)) +/** @} */ + + +/** @name VMX MSRs - Misc VMX info. + * @{ + */ +/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */ +#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f) +/** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */ +#define MSR_IA32_VMX_MISC_STORE_EFERLMA_VMEXIT(a) (((a) >> 5) & 1) +/** Activity states supported by the implementation. */ +#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7) +/** Number of CR3 target values supported by the processor. (0-256) */ +#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF) +/** Maximum nr of MSRs in the VMCS. (N+1)*512. */ +#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512) +/** Whether RDMSR can be used to read IA32_SMBASE_MSR in SMM. */ +#define MSR_IA32_VMX_MISC_RDMSR_SMBASE_MSR_SMM(a) (((a) >> 15) & 1) +/** Whether bit 2 of IA32_SMM_MONITOR_CTL can be set to 1. */ +#define MSR_IA32_VMX_MISC_SMM_MONITOR_CTL_B2(a) (((a) >> 28) & 1) +/** Whether VMWRITE can be used to write VM-exit information fields. */ +#define MSR_IA32_VMX_MISC_VMWRITE_VMEXIT_INFO(a) (((a) >> 29) & 1) +/** MSEG revision identifier used by the processor. */ +#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32) +/** @} */ + + +/** @name VMX MSRs - VMCS enumeration field info + * @{ + */ +/** Highest field index. */ +#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF) +/** @} */ + + +/** @name MSR_IA32_VMX_EPT_VPID_CAPS; EPT capabilities MSR + * @{ + */ +#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_X_ONLY RT_BIT_64(0) +#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_W_ONLY RT_BIT_64(1) +#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_WX_ONLY RT_BIT_64(2) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_21_BITS RT_BIT_64(3) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_30_BITS RT_BIT_64(4) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_39_BITS RT_BIT_64(5) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_48_BITS RT_BIT_64(6) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_57_BITS RT_BIT_64(7) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_UC RT_BIT_64(8) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WC RT_BIT_64(9) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WT RT_BIT_64(12) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WP RT_BIT_64(13) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WB RT_BIT_64(14) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_21_BITS RT_BIT_64(16) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_30_BITS RT_BIT_64(17) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_39_BITS RT_BIT_64(18) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_48_BITS RT_BIT_64(19) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT RT_BIT_64(20) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT RT_BIT_64(25) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS RT_BIT_64(26) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID RT_BIT_64(32) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_INDIV_ADDR RT_BIT_64(40) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT RT_BIT_64(41) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS RT_BIT_64(42) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43) + +/** @} */ + +/** @name Extended Page Table Pointer (EPTP) + * @{ + */ +/** Uncachable EPT paging structure memory type. */ +#define VMX_EPT_MEMTYPE_UC 0 +/** Write-back EPT paging structure memory type. */ +#define VMX_EPT_MEMTYPE_WB 6 +/** Shift value to get the EPT page walk length (bits 5-3) */ +#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3 +/** Mask value to get the EPT page walk length (bits 5-3) */ +#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7 +/** Default EPT page-walk length (1 less than the actual EPT page-walk + * length) */ +#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3 +/** @} */ + + +/** @name VMCS field encoding - 16 bits guest fields + * @{ + */ +#define VMX_VMCS16_GUEST_FIELD_VPID 0x0 +#define VMX_VMCS16_GUEST_FIELD_ES 0x800 +#define VMX_VMCS16_GUEST_FIELD_CS 0x802 +#define VMX_VMCS16_GUEST_FIELD_SS 0x804 +#define VMX_VMCS16_GUEST_FIELD_DS 0x806 +#define VMX_VMCS16_GUEST_FIELD_FS 0x808 +#define VMX_VMCS16_GUEST_FIELD_GS 0x80A +#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C +#define VMX_VMCS16_GUEST_FIELD_TR 0x80E +/** @} */ + +/** @name VMCS field encoding - 16 bits host fields + * @{ + */ +#define VMX_VMCS16_HOST_FIELD_ES 0xC00 +#define VMX_VMCS16_HOST_FIELD_CS 0xC02 +#define VMX_VMCS16_HOST_FIELD_SS 0xC04 +#define VMX_VMCS16_HOST_FIELD_DS 0xC06 +#define VMX_VMCS16_HOST_FIELD_FS 0xC08 +#define VMX_VMCS16_HOST_FIELD_GS 0xC0A +#define VMX_VMCS16_HOST_FIELD_TR 0xC0C +/** @} */ + +/** @name VMCS field encoding - 64 bits host fields + * @{ + */ +#define VMX_VMCS64_HOST_FIELD_PAT_FULL 0x2C00 +#define VMX_VMCS64_HOST_FIELD_PAT_HIGH 0x2C01 +#define VMX_VMCS64_HOST_FIELD_EFER_FULL 0x2C02 +#define VMX_VMCS64_HOST_FIELD_EFER_HIGH 0x2C03 +#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */ +#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */ +/** @} */ + + +/** @name VMCS field encoding - 64 Bits control fields + * @{ + */ +#define VMX_VMCS64_CTRL_IO_BITMAP_A_FULL 0x2000 +#define VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH 0x2001 +#define VMX_VMCS64_CTRL_IO_BITMAP_B_FULL 0x2002 +#define VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH 0x2003 + +/* Optional */ +#define VMX_VMCS64_CTRL_MSR_BITMAP_FULL 0x2004 +#define VMX_VMCS64_CTRL_MSR_BITMAP_HIGH 0x2005 + +#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL 0x2006 +#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH 0x2007 +#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL 0x2008 +#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH 0x2009 + +#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL 0x200A +#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH 0x200B + +#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL 0x200C +#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH 0x200D + +#define VMX_VMCS64_CTRL_TSC_OFFSET_FULL 0x2010 +#define VMX_VMCS64_CTRL_TSC_OFFSET_HIGH 0x2011 + +/** Optional (VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW) */ +#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_FULL 0x2012 +#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_HIGH 0x2013 + +/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */ +#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL 0x2014 +#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH 0x2015 + +/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC) */ +#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL 0x2018 +#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH 0x2019 + +/** Extended page table pointer. */ +#define VMX_VMCS64_CTRL_EPTP_FULL 0x201a +#define VMX_VMCS64_CTRL_EPTP_HIGH 0x201b + +/** Extended page table pointer lists. */ +#define VMX_VMCS64_CTRL_EPTP_LIST_FULL 0x2024 +#define VMX_VMCS64_CTRL_EPTP_LIST_HIGH 0x2025 + +/** VM-exit guest phyiscal address. */ +#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL 0x2400 +#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_HIGH 0x2401 +/** @} */ + + +/** @name VMCS field encoding - 64 Bits guest fields + * @{ + */ +#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL 0x2800 +#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH 0x2801 +#define VMX_VMCS64_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */ +#define VMX_VMCS64_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */ +#define VMX_VMCS64_GUEST_PAT_FULL 0x2804 +#define VMX_VMCS64_GUEST_PAT_HIGH 0x2805 +#define VMX_VMCS64_GUEST_EFER_FULL 0x2806 +#define VMX_VMCS64_GUEST_EFER_HIGH 0x2807 +#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */ +#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */ +#define VMX_VMCS64_GUEST_PDPTE0_FULL 0x280A +#define VMX_VMCS64_GUEST_PDPTE0_HIGH 0x280B +#define VMX_VMCS64_GUEST_PDPTE1_FULL 0x280C +#define VMX_VMCS64_GUEST_PDPTE1_HIGH 0x280D +#define VMX_VMCS64_GUEST_PDPTE2_FULL 0x280E +#define VMX_VMCS64_GUEST_PDPTE2_HIGH 0x280F +#define VMX_VMCS64_GUEST_PDPTE3_FULL 0x2810 +#define VMX_VMCS64_GUEST_PDPTE3_HIGH 0x2811 +/** @} */ + + +/** @name VMCS field encoding - 32 Bits control fields + * @{ + */ +#define VMX_VMCS32_CTRL_PIN_EXEC 0x4000 +#define VMX_VMCS32_CTRL_PROC_EXEC 0x4002 +#define VMX_VMCS32_CTRL_EXCEPTION_BITMAP 0x4004 +#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK 0x4006 +#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH 0x4008 +#define VMX_VMCS32_CTRL_CR3_TARGET_COUNT 0x400A +#define VMX_VMCS32_CTRL_EXIT 0x400C +#define VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT 0x400E +#define VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT 0x4010 +#define VMX_VMCS32_CTRL_ENTRY 0x4012 +#define VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014 +#define VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO 0x4016 +#define VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018 +#define VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH 0x401A +#define VMX_VMCS32_CTRL_TPR_THRESHOLD 0x401C +#define VMX_VMCS32_CTRL_PROC_EXEC2 0x401E +/** @} */ + + +/** @name VMX_VMCS_CTRL_PIN_EXEC + * @{ + */ +/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ +#define VMX_VMCS_CTRL_PIN_EXEC_EXT_INT_EXIT RT_BIT(0) +/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ +#define VMX_VMCS_CTRL_PIN_EXEC_NMI_EXIT RT_BIT(3) +/** Virtual NMIs. */ +#define VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI RT_BIT(5) +/** Activate VMX preemption timer. */ +#define VMX_VMCS_CTRL_PIN_EXEC_PREEMPT_TIMER RT_BIT(6) +/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */ +/** @} */ + +/** @name VMX_VMCS_CTRL_PROC_EXEC + * @{ + */ +/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */ +#define VMX_VMCS_CTRL_PROC_EXEC_INT_WINDOW_EXIT RT_BIT(2) +/** Use timestamp counter offset. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_TSC_OFFSETTING RT_BIT(3) +/** VM Exit when executing the HLT instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_HLT_EXIT RT_BIT(7) +/** VM Exit when executing the INVLPG instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_INVLPG_EXIT RT_BIT(9) +/** VM Exit when executing the MWAIT instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MWAIT_EXIT RT_BIT(10) +/** VM Exit when executing the RDPMC instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_RDPMC_EXIT RT_BIT(11) +/** VM Exit when executing the RDTSC/RDTSCP instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT RT_BIT(12) +/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR3_LOAD_EXIT RT_BIT(15) +/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR3_STORE_EXIT RT_BIT(16) +/** VM Exit on CR8 loads. */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT RT_BIT(19) +/** VM Exit on CR8 stores. */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT RT_BIT(20) +/** Use TPR shadow. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW RT_BIT(21) +/** VM Exit when virtual nmi blocking is disabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC_NMI_WINDOW_EXIT RT_BIT(22) +/** VM Exit when executing a MOV DRx instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT RT_BIT(23) +/** VM Exit when executing IO instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC_UNCOND_IO_EXIT RT_BIT(24) +/** Use IO bitmaps. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_IO_BITMAPS RT_BIT(25) +/** Monitor trap flag. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG RT_BIT(27) +/** Use MSR bitmaps. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_MSR_BITMAPS RT_BIT(28) +/** VM Exit when executing the MONITOR instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_EXIT RT_BIT(29) +/** VM Exit when executing the PAUSE instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_PAUSE_EXIT RT_BIT(30) +/** Determines whether the secondary processor based VM-execution controls are used. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31) +/** @} */ + +/** @name VMX_VMCS_CTRL_PROC_EXEC2 + * @{ + */ +/** Virtualize APIC access. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0) +/** EPT supported/enabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1) +/** Descriptor table instructions cause VM-exits. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_TABLE_EXIT RT_BIT(2) +/** RDTSCP supported/enabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3) +/** Virtualize x2APIC mode. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_X2APIC RT_BIT(4) +/** VPID supported/enabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5) +/** VM Exit when executing the WBINVD instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6) +/** Unrestricted guest execution. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_UNRESTRICTED_GUEST RT_BIT(7) +/** A specified nr of pause loops cause a VM-exit. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10) +/** VM Exit when executing RDRAND instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_RDRAND_EXIT RT_BIT(11) +/** Enables INVPCID instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_INVPCID RT_BIT(12) +/** Enables VMFUNC instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC RT_BIT(13) +/** @} */ + + +/** @name VMX_VMCS_CTRL_ENTRY + * @{ + */ +/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG RT_BIT(2) +/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */ +#define VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST RT_BIT(9) +/** In SMM mode after VM-entry. */ +#define VMX_VMCS_CTRL_ENTRY_ENTRY_SMM RT_BIT(10) +/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */ +#define VMX_VMCS_CTRL_ENTRY_DEACTIVATE_DUALMON RT_BIT(11) +/** Whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PERF_MSR RT_BIT(13) +/** Whether the guest IA32_PAT MSR is loaded on VM entry. */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PAT_MSR RT_BIT(14) +/** Whether the guest IA32_EFER MSR is loaded on VM entry. */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_EFER_MSR RT_BIT(15) +/** @} */ + + +/** @name VMX_VMCS_CTRL_EXIT + * @{ + */ +/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_EXIT_SAVE_DEBUG RT_BIT(2) +/** Return to long mode after a VM-exit. */ +#define VMX_VMCS_CTRL_EXIT_HOST_ADDR_SPACE_SIZE RT_BIT(9) +/** Whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_LOAD_PERF_MSR RT_BIT(12) +/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */ +#define VMX_VMCS_CTRL_EXIT_ACK_EXT_INT RT_BIT(15) +/** Whether the guest IA32_PAT MSR is saved on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_PAT_MSR RT_BIT(18) +/** Whether the host IA32_PAT MSR is loaded on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_PAT_MSR RT_BIT(19) +/** Whether the guest IA32_EFER MSR is saved on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_EFER_MSR RT_BIT(20) +/** Whether the host IA32_EFER MSR is loaded on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_EFER_MSR RT_BIT(21) +/** Whether the value of the VMX preemption timer is saved on every VM exit. */ +#define VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER RT_BIT(22) +/** @} */ + + +/** @name VMX_VMCS_CTRL_VMFUNC + * @{ + */ +/** EPTP-switching function changes the value of the EPTP to one chosen from the EPTP list. */ +#define VMX_VMCS_CTRL_VMFUNC_EPTP_SWITCHING RT_BIT_64(0) +/** @} */ + + +/** @name VMCS field encoding - 32 Bits read-only fields + * @{ + */ +#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400 +#define VMX_VMCS32_RO_EXIT_REASON 0x4402 +#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404 +#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE 0x4406 +#define VMX_VMCS32_RO_IDT_INFO 0x4408 +#define VMX_VMCS32_RO_IDT_ERROR_CODE 0x440A +#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C +#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E +/** @} */ + +/** @name VMX_VMCS32_RO_EXIT_REASON + * @{ + */ +#define VMX_EXIT_REASON_BASIC(a) ((a) & 0xffff) +/** @} */ + +/** @name VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO + * @{ + */ +#define VMX_ENTRY_INTERRUPTION_INFO_IS_VALID(a) RT_BOOL((a) & RT_BIT(31)) +#define VMX_ENTRY_INTERRUPTION_INFO_TYPE_SHIFT 8 +#define VMX_ENTRY_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_ENTRY_INTERRUPTION_INFO_TYPE_SHIFT) & 7) +/** @} */ + + +/** @name VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO + * @{ + */ +#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) ((a) & 0xff) +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) (((a) >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7) +#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11) +#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) RT_BOOL((a) & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID) +#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) ((a) & RT_BIT(12)) +#define VMX_EXIT_INTERRUPTION_INFO_VALID RT_BIT(31) +#define VMX_EXIT_INTERRUPTION_INFO_IS_VALID(a) RT_BOOL((a) & RT_BIT(31)) +/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */ +#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) ((a) & ~RT_BIT(12)) +/** @} */ + +/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE + * @{ + */ +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT 0 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 3 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT 4 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_PRIV_SW_XCPT 5 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_XCPT 6 +/** @} */ + +/** @name VMX_VMCS32_RO_IDT_VECTORING_INFO + * @{ + */ +#define VMX_IDT_VECTORING_INFO_VECTOR(a) ((a) & 0xff) +#define VMX_IDT_VECTORING_INFO_TYPE_SHIFT 8 +#define VMX_IDT_VECTORING_INFO_TYPE(a) (((a) >> VMX_IDT_VECTORING_INFO_TYPE_SHIFT) & 7) +#define VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID RT_BIT(11) +#define VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(a) RT_BOOL((a) & VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID) +#define VMX_IDT_VECTORING_INFO_VALID(a) ((a) & RT_BIT(31)) +#define VMX_ENTRY_INT_INFO_FROM_EXIT_IDT_INFO(a) ((a) & ~RT_BIT(12)) +/** @} */ + +/** @name VMX_VMCS_RO_IDT_VECTORING_INFO_TYPE + * @{ + */ +#define VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 0 +#define VMX_IDT_VECTORING_INFO_TYPE_NMI 2 +#define VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 3 +#define VMX_IDT_VECTORING_INFO_TYPE_SW_INT 4 +#define VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT 5 +#define VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT 6 +/** @} */ + + +/** @name VMCS field encoding - 32 Bits guest state fields + * @{ + */ +#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800 +#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802 +#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804 +#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806 +#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808 +#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A +#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C +#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E +#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810 +#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812 +#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814 +#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816 +#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818 +#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A +#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C +#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E +#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820 +#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822 +#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824 +#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826 +#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */ +#define VMX_VMCS32_GUEST_PREEMPT_TIMER_VALUE 0x482E +/** @} */ + + +/** @name VMX_VMCS_GUEST_ACTIVITY_STATE + * @{ + */ +/** The logical processor is active. */ +#define VMX_VMCS_GUEST_ACTIVITY_ACTIVE 0x0 +/** The logical processor is inactive, because executed a HLT instruction. */ +#define VMX_VMCS_GUEST_ACTIVITY_HLT 0x1 +/** The logical processor is inactive, because of a triple fault or other serious error. */ +#define VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN 0x2 +/** The logical processor is inactive, because it's waiting for a startup-IPI */ +#define VMX_VMCS_GUEST_ACTIVITY_SIPI_WAIT 0x3 +/** @} */ + + +/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE + * @{ + */ +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0) +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1) +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2) +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3) +/** @} */ + + +/** @name VMCS field encoding - 32 Bits host state fields + * @{ + */ +#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00 +/** @} */ + +/** @name Natural width control fields + * @{ + */ +#define VMX_VMCS_CTRL_CR0_MASK 0x6000 +#define VMX_VMCS_CTRL_CR4_MASK 0x6002 +#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004 +#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006 +#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008 +#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A +#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C +#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E +/** @} */ + + +/** @name Natural width read-only data fields + * @{ + */ +#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400 +#define VMX_VMCS_RO_IO_RCX 0x6402 +#define VMX_VMCS_RO_IO_RSX 0x6404 +#define VMX_VMCS_RO_IO_RDI 0x6406 +#define VMX_VMCS_RO_IO_RIP 0x6408 +#define VMX_VMCS_RO_EXIT_GUEST_LINEAR_ADDR 0x640A +/** @} */ + + +/** @name VMX_VMCS_RO_EXIT_QUALIFICATION + * @{ + */ +/** 0-2: Debug register number */ +#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) ((a) & 7) +/** 3: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) (((a) >> 3) & 1) +/** 4: Direction of move (0 = write, 1 = read) */ +#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) (((a) >> 4) & 1) +/** 5-7: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) (((a) >> 5) & 7) +/** 8-11: General purpose register number. */ +#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) (((a) >> 8) & 0xF) +/** Rest: reserved. */ +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values + * @{ + */ +#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0 +#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1 +/** @} */ + + + +/** @name CRx accesses + * @{ + */ +/** 0-3: Control register number (0 for CLTS & LMSW) */ +#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) ((a) & 0xF) +/** 4-5: Access type. */ +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) (((a) >> 4) & 3) +/** 6: LMSW operand type */ +#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) (((a) >> 6) & 1) +/** 7: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) (((a) >> 7) & 1) +/** 8-11: General purpose register number (0 for CLTS & LMSW). */ +#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) (((a) >> 8) & 0xF) +/** 12-15: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) (((a) >> 12) & 0xF) +/** 16-31: LMSW source data (else 0). */ +#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) (((a) >> 16) & 0xFFFF) +/** Rest: reserved. */ +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS + * @{ + */ +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0 +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1 +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2 +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3 +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH + * @{ + */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) ((a) & 0xffff) +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) (((a) >> 30) & 0x3) +/** Task switch caused by a call instruction. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0 +/** Task switch caused by an iret instruction. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1 +/** Task switch caused by a jmp instruction. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2 +/** Task switch caused by an interrupt gate. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3 +/** @} */ + + +/** @name VMX_EXIT_EPT_VIOLATION + * @{ + */ +/** Set if the violation was caused by a data read. */ +#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0) +/** Set if the violation was caused by a data write. */ +#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1) +/** Set if the violation was caused by an insruction fetch. */ +#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2) +/** AND of the present bit of all EPT structures. */ +#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3) +/** AND of the write bit of all EPT structures. */ +#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4) +/** AND of the execute bit of all EPT structures. */ +#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5) +/** Set if the guest linear address field contains the faulting address. */ +#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7) +/** If bit 7 is one: (reserved otherwise) + * 1 - violation due to physical address access. + * 0 - violation caused by page walk or access/dirty bit updates + */ +#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8) +/** @} */ + + +/** @name VMX_EXIT_PORT_IO + * @{ + */ +/** 0-2: IO operation width. */ +#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) ((a) & 7) +/** 3: IO operation direction. */ +#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) (((a) >> 3) & 1) +/** 4: String IO operation (INS / OUTS). */ +#define VMX_EXIT_QUALIFICATION_IO_IS_STRING(a) RT_BOOL((a) & RT_BIT_64(4)) +/** 5: Repeated IO operation. */ +#define VMX_EXIT_QUALIFICATION_IO_IS_REP(a) RT_BOOL((a) & RT_BIT_64(5)) +/** 6: Operand encoding. */ +#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) (((a) >> 6) & 1) +/** 16-31: IO Port (0-0xffff). */ +#define VMX_EXIT_QUALIFICATION_IO_PORT(a) (((a) >> 16) & 0xffff) +/* Rest reserved. */ +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION + * @{ + */ +#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0 +#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1 +/** @} */ + + +/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING + * @{ + */ +#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0 +#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1 +/** @} */ + +/** @name VMX_EXIT_APIC_ACCESS + * @{ + */ +/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */ +#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) ((a) & 0xfff) +/** 12-15: Access type. */ +#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a) & 0xf000) +/* Rest reserved. */ +/** @} */ + + +/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types + * @{ + */ +/** Linear read access. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0 +/** Linear write access. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1 +/** Linear instruction fetch access. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2 +/** Linear read/write access during event delivery. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3 +/** Physical read/write access during event delivery. */ +#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10 +/** Physical access for an instruction fetch or during instruction execution. */ +#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15 +/** @} */ + +/** @} */ + +/** @name VMCS field encoding - Natural width guest state fields + * @{ + */ +#define VMX_VMCS_GUEST_CR0 0x6800 +#define VMX_VMCS_GUEST_CR3 0x6802 +#define VMX_VMCS_GUEST_CR4 0x6804 +#define VMX_VMCS_GUEST_ES_BASE 0x6806 +#define VMX_VMCS_GUEST_CS_BASE 0x6808 +#define VMX_VMCS_GUEST_SS_BASE 0x680A +#define VMX_VMCS_GUEST_DS_BASE 0x680C +#define VMX_VMCS_GUEST_FS_BASE 0x680E +#define VMX_VMCS_GUEST_GS_BASE 0x6810 +#define VMX_VMCS_GUEST_LDTR_BASE 0x6812 +#define VMX_VMCS_GUEST_TR_BASE 0x6814 +#define VMX_VMCS_GUEST_GDTR_BASE 0x6816 +#define VMX_VMCS_GUEST_IDTR_BASE 0x6818 +#define VMX_VMCS_GUEST_DR7 0x681A +#define VMX_VMCS_GUEST_RSP 0x681C +#define VMX_VMCS_GUEST_RIP 0x681E +#define VMX_VMCS_GUEST_RFLAGS 0x6820 +#define VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS 0x6822 +#define VMX_VMCS_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */ +#define VMX_VMCS_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */ +/** @} */ + + +/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS + * @{ + */ +/** Hardware breakpoint 0 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0) +/** Hardware breakpoint 1 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1) +/** Hardware breakpoint 2 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2) +/** Hardware breakpoint 3 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3) +/** At least one data or IO breakpoint was hit. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12) +/** A debug exception would have been triggered by single-step execution mode. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14) +/** Bits 4-11, 13 and 15-63 are reserved. */ + +/** @} */ + +/** @name VMCS field encoding - Natural width host state fields + * @{ + */ +#define VMX_VMCS_HOST_CR0 0x6C00 +#define VMX_VMCS_HOST_CR3 0x6C02 +#define VMX_VMCS_HOST_CR4 0x6C04 +#define VMX_VMCS_HOST_FS_BASE 0x6C06 +#define VMX_VMCS_HOST_GS_BASE 0x6C08 +#define VMX_VMCS_HOST_TR_BASE 0x6C0A +#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C +#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E +#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10 +#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12 +#define VMX_VMCS_HOST_RSP 0x6C14 +#define VMX_VMCS_HOST_RIP 0x6C16 +/** @} */ + +/** @} */ + + +/** @defgroup grp_vmx_asm vmx assembly helpers + * @ingroup grp_vmx + * @{ + */ + +/** + * Restores some host-state fields that need not be done on every VM-exit. + * + * @returns VBox status code. + * @param fRestoreHostFlags Flags of which host registers needs to be + * restored. + * @param pRestoreHost Pointer to the host-restore structure. + */ +DECLASM(int) VMXRestoreHostState(uint32_t fRestoreHostFlags, PVMXRESTOREHOST pRestoreHost); + + +/** + * Dispatches an NMI to the host. + */ +DECLASM(int) VMXDispatchHostNmi(void); + + +/** + * Executes VMXON + * + * @returns VBox status code + * @param pVMXOn Physical address of VMXON structure + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXEnable(RTHCPHYS pVMXOn); +#else +DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "push %3 \n\t" + "push %2 \n\t" + ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t" + "ja 2f \n\t" + "je 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $"RT_XSTR(VERR_VMX_VMXON_FAILED)", %0 \n\t" + "2: \n\t" + "add $8, %%esp \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */ + "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */ + :"memory" + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_on(&pVMXOn); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMXON_PTR : VERR_VMX_VMXON_FAILED; + +# else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [pVMXOn+4] + push dword ptr [pVMXOn] + _emit 0xF3 + _emit 0x0F + _emit 0xC7 + _emit 0x34 + _emit 0x24 /* VMXON [esp] */ + jnc vmxon_good + mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR + jmp the_end + +vmxon_good: + jnz the_end + mov dword ptr [rc], VERR_VMX_VMXON_FAILED +the_end: + add esp, 8 + } + return rc; +# endif +} +#endif + + +/** + * Executes VMXOFF + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(void) VMXDisable(void); +#else +DECLINLINE(void) VMXDisable(void) +{ +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__ ( + ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t" + ); + +# elif VMX_USE_MSC_INTRINSICS + __vmx_off(); + +# else + __asm + { + _emit 0x0F + _emit 0x01 + _emit 0xC4 /* VMXOFF */ + } +# endif +} +#endif + + +/** + * Executes VMCLEAR + * + * @returns VBox status code + * @param pVMCS Physical address of VM control structure + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXClearVmcs(RTHCPHYS pVMCS); +#else +DECLINLINE(int) VMXClearVmcs(RTHCPHYS pVMCS) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "push %3 \n\t" + "push %2 \n\t" + ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t" + "jnc 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "1: \n\t" + "add $8, %%esp \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ + "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */ + :"memory" + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_vmclear(&pVMCS); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return VERR_VMX_INVALID_VMCS_PTR; + +# else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [pVMCS+4] + push dword ptr [pVMCS] + _emit 0x66 + _emit 0x0F + _emit 0xC7 + _emit 0x34 + _emit 0x24 /* VMCLEAR [esp] */ + jnc success + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR +success: + add esp, 8 + } + return rc; +# endif +} +#endif + + +/** + * Executes VMPTRLD + * + * @returns VBox status code + * @param pVMCS Physical address of VMCS structure + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXActivateVmcs(RTHCPHYS pVMCS); +#else +DECLINLINE(int) VMXActivateVmcs(RTHCPHYS pVMCS) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "push %3 \n\t" + "push %2 \n\t" + ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t" + "jnc 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "1: \n\t" + "add $8, %%esp \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ + "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */ + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_vmptrld(&pVMCS); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return VERR_VMX_INVALID_VMCS_PTR; + +# else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [pVMCS+4] + push dword ptr [pVMCS] + _emit 0x0F + _emit 0xC7 + _emit 0x34 + _emit 0x24 /* VMPTRLD [esp] */ + jnc success + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR + +success: + add esp, 8 + } + return rc; +# endif +} +#endif + +/** + * Executes VMPTRST + * + * @returns VBox status code + * @param pVMCS Address that will receive the current pointer + */ +DECLASM(int) VMXGetActivatedVmcs(RTHCPHYS *pVMCS); + +/** + * Executes VMWRITE + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param u32Val 32 bits value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val); +#else +DECLINLINE(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t" + "ja 2f \n\t" + "je 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" + "2: \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "a"(idxField), + "d"(u32Val) + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_vmwrite(idxField, u32Val); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; + +#else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [u32Val] + mov eax, [idxField] + _emit 0x0F + _emit 0x79 + _emit 0x04 + _emit 0x24 /* VMWRITE eax, [esp] */ + jnc valid_vmcs + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR + jmp the_end + +valid_vmcs: + jnz the_end + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD +the_end: + add esp, 4 + } + return rc; +# endif +} +#endif + +/** + * Executes VMWRITE + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param u64Val 16, 32 or 64 bits value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if !defined(RT_ARCH_X86) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +# if !VMX_USE_MSC_INTRINSICS || ARCH_BITS != 64 +DECLASM(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val); +# else /* VMX_USE_MSC_INTRINSICS */ +DECLINLINE(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val) +{ + unsigned char rcMsc = __vmx_vmwrite(idxField, u64Val); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; +} +# endif /* VMX_USE_MSC_INTRINSICS */ +#else +# define VMXWriteVmcs64(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) /** @todo dead ugly, picking up pVCpu like this */ +VMMR0DECL(int) VMXWriteVmcs64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val); +#endif + +#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL +# define VMXWriteVmcsHstN(idxField, uVal) HMVMX_IS_64BIT_HOST_MODE() ? \ + VMXWriteVmcs64(idxField, uVal) \ + : VMXWriteVmcs32(idxField, uVal) +# define VMXWriteVmcsGstN(idxField, u64Val) (pVCpu->CTX_SUFF(pVM)->hm.s.fAllow64BitGuests) ? \ + VMXWriteVmcs64(idxField, u64Val) \ + : VMXWriteVmcs32(idxField, u64Val) +#elif ARCH_BITS == 32 +# define VMXWriteVmcsHstN VMXWriteVmcs32 +# define VMXWriteVmcsGstN(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) +# else /* ARCH_BITS == 64 */ +# define VMXWriteVmcsHstN VMXWriteVmcs64 +# define VMXWriteVmcsGstN VMXWriteVmcs64 +# endif + + +/** + * Invalidate a page using invept + * @returns VBox status code + * @param enmFlush Type of flush + * @param pDescriptor Descriptor + */ +DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor); + +/** + * Invalidate a page using invvpid + * @returns VBox status code + * @param enmFlush Type of flush + * @param pDescriptor Descriptor + */ +DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor); + +/** + * Executes VMREAD + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param pData Ptr to store VM field value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData); +#else +DECLINLINE(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "movl $"RT_XSTR(VINF_SUCCESS)", %0 \n\t" + ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t" + "ja 2f \n\t" + "je 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" + "2: \n\t" + :"=&r"(rc), + "=d"(*pData) + :"a"(idxField), + "d"(0) + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc; +# if ARCH_BITS == 32 + rcMsc = __vmx_vmread(idxField, pData); +# else + uint64_t u64Tmp; + rcMsc = __vmx_vmread(idxField, &u64Tmp); + *pData = (uint32_t)u64Tmp; +# endif + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; + +#else + int rc = VINF_SUCCESS; + __asm + { + sub esp, 4 + mov dword ptr [esp], 0 + mov eax, [idxField] + _emit 0x0F + _emit 0x78 + _emit 0x04 + _emit 0x24 /* VMREAD eax, [esp] */ + mov edx, pData + pop dword ptr [edx] + jnc valid_vmcs + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR + jmp the_end + +valid_vmcs: + jnz the_end + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD +the_end: + } + return rc; +# endif +} +#endif + +/** + * Executes VMREAD + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param pData Ptr to store VM field value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if (!defined(RT_ARCH_X86) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData); +#else +DECLINLINE(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData) +{ +# if VMX_USE_MSC_INTRINSICS + unsigned char rcMsc; +# if ARCH_BITS == 32 + size_t uLow; + size_t uHigh; + rcMsc = __vmx_vmread(idxField, &uLow); + rcMsc |= __vmx_vmread(idxField + 1, &uHigh); + *pData = RT_MAKE_U64(uLow, uHigh); +# else + rcMsc = __vmx_vmread(idxField, pData); +# endif + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; + +# elif ARCH_BITS == 32 + int rc; + uint32_t val_hi, val; + rc = VMXReadVmcs32(idxField, &val); + rc |= VMXReadVmcs32(idxField + 1, &val_hi); + AssertRC(rc); + *pData = RT_MAKE_U64(val, val_hi); + return rc; + +# else +# error "Shouldn't be here..." +# endif +} +#endif + +/** + * Gets the last instruction error value from the current VMCS + * + * @returns error value + */ +DECLINLINE(uint32_t) VMXGetLastError(void) +{ +#if ARCH_BITS == 64 + uint64_t uLastError = 0; + int rc = VMXReadVmcs64(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); + AssertRC(rc); + return (uint32_t)uLastError; + +#else /* 32-bit host: */ + uint32_t uLastError = 0; + int rc = VMXReadVmcs32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); + AssertRC(rc); + return uLastError; +#endif +} + +#ifdef IN_RING0 +VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); +VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys); +#endif /* IN_RING0 */ + +/** @} */ + +#endif + diff --git a/include/VBox/vmm/hm_vmx.mac b/include/VBox/vmm/hm_vmx.mac new file mode 100644 index 00000000..3a3a1c7b --- /dev/null +++ b/include/VBox/vmm/hm_vmx.mac @@ -0,0 +1,181 @@ +;; @file +; HM - VMX Structures and Definitions. +; + +; +; 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; +; 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. +; + +%define VMX_VMCS_GUEST_FIELD_ES 0800h +%define VMX_VMCS_GUEST_FIELD_CS 0802h +%define VMX_VMCS_GUEST_FIELD_SS 0804h +%define VMX_VMCS_GUEST_FIELD_DS 0806h +%define VMX_VMCS_GUEST_FIELD_FS 0808h +%define VMX_VMCS_GUEST_FIELD_GS 080Ah +%define VMX_VMCS_GUEST_FIELD_LDTR 080Ch +%define VMX_VMCS_GUEST_FIELD_TR 080Eh +%define VMX_VMCS_HOST_FIELD_ES 0C00h +%define VMX_VMCS_HOST_FIELD_CS 0C02h +%define VMX_VMCS_HOST_FIELD_SS 0C04h +%define VMX_VMCS_HOST_FIELD_DS 0C06h +%define VMX_VMCS_HOST_FIELD_FS 0C08h +%define VMX_VMCS_HOST_FIELD_GS 0C0Ah +%define VMX_VMCS_HOST_FIELD_TR 0C0Ch +%define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 02000h +%define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 02001h +%define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 02002h +%define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 02003h +%define VMX_VMCS_CTRL_MSR_BITMAP_FULL 02004h +%define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 02005h +%define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 02006h +%define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 02007h +%define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 02008h +%define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 02009h +%define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0200Ah +%define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0200Bh +%define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0200Ch +%define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0200Dh +%define VMX_VMCS_CTRL_TSC_OFFSET_FULL 02010h +%define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 02011h +%define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 02012h +%define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 02013h +%define VMX_VMCS_GUEST_LINK_PTR_FULL 02800h +%define VMX_VMCS_GUEST_LINK_PTR_HIGH 02801h +%define VMX_VMCS_GUEST_DEBUGCTL_FULL 02802h +%define VMX_VMCS_GUEST_DEBUGCTL_HIGH 02803h +%define VMX_VMCS_CTRL_PIN_EXEC 04000h +%define VMX_VMCS_CTRL_PROC_EXEC 04002h +%define VMX_VMCS_CTRL_EXCEPTION_BITMAP 04004h +%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 04006h +%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 04008h +%define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0400Ah +%define VMX_VMCS_CTRL_EXIT 0400Ch +%define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0400Eh +%define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 04010h +%define VMX_VMCS_CTRL_ENTRY 04012h +%define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 04014h +%define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 04016h +%define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 04018h +%define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0401Ah +%define VMX_VMCS_CTRL_TRP_TRESHOLD 0401Ch +%define VMX_VMCS_RO_VM_INSTR_ERROR 04400h +%define VMX_VMCS_RO_EXIT_REASON 04402h +%define VMX_VMCS_RO_EXIT_INTERRUPTION_INFO 04404h +%define VMX_VMCS_RO_EXIT_INTERRUPTION_ERRCODE 04406h +%define VMX_VMCS_RO_IDT_INFO 04408h +%define VMX_VMCS_RO_IDT_ERRCODE 0440Ah +%define VMX_VMCS_RO_EXIT_INSTR_LENGTH 0440Ch +%define VMX_VMCS_RO_EXIT_INSTR_INFO 0440Eh +%define VMX_VMCS_GUEST_ES_LIMIT 04800h +%define VMX_VMCS_GUEST_CS_LIMIT 04802h +%define VMX_VMCS_GUEST_SS_LIMIT 04804h +%define VMX_VMCS_GUEST_DS_LIMIT 04806h +%define VMX_VMCS_GUEST_FS_LIMIT 04808h +%define VMX_VMCS_GUEST_GS_LIMIT 0480Ah +%define VMX_VMCS_GUEST_LDTR_LIMIT 0480Ch +%define VMX_VMCS_GUEST_TR_LIMIT 0480Eh +%define VMX_VMCS_GUEST_GDTR_LIMIT 04810h +%define VMX_VMCS_GUEST_IDTR_LIMIT 04812h +%define VMX_VMCS_GUEST_ES_ACCESS_RIGHTS 04814h +%define VMX_VMCS_GUEST_CS_ACCESS_RIGHTS 04816h +%define VMX_VMCS_GUEST_SS_ACCESS_RIGHTS 04818h +%define VMX_VMCS_GUEST_DS_ACCESS_RIGHTS 0481Ah +%define VMX_VMCS_GUEST_FS_ACCESS_RIGHTS 0481Ch +%define VMX_VMCS_GUEST_GS_ACCESS_RIGHTS 0481Eh +%define VMX_VMCS_GUEST_LDTR_ACCESS_RIGHTS 04820h +%define VMX_VMCS_GUEST_TR_ACCESS_RIGHTS 04822h +%define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE 04824h +%define VMX_VMCS_GUEST_ACTIVITY_STATE 04826h +%define VMX_VMCS_GUEST_SYSENTER_CS 0482Ah +%define VMX_VMCS_CTRL_CR0_MASK 06000h +%define VMX_VMCS_CTRL_CR4_MASK 06002h +%define VMX_VMCS_CTRL_CR0_READ_SHADOW 06004h +%define VMX_VMCS_CTRL_CR4_READ_SHADOW 06006h +%define VMX_VMCS_CTRL_CR3_TARGET_VAL0 06008h +%define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0600Ah +%define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0600Ch +%define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0600Eh +%define VMX_VMCS_RO_EXIT_QUALIFICATION 06400h +%define VMX_VMCS_RO_IO_RCX 06402h +%define VMX_VMCS_RO_IO_RSX 06404h +%define VMX_VMCS_RO_IO_RDI 06406h +%define VMX_VMCS_RO_IO_RIP 06408h +%define VMX_VMCS_GUEST_LINEAR_ADDR 0640Ah +%define VMX_VMCS64_GUEST_CR0 06800h +%define VMX_VMCS64_GUEST_CR3 06802h +%define VMX_VMCS64_GUEST_CR4 06804h +%define VMX_VMCS64_GUEST_ES_BASE 06806h +%define VMX_VMCS64_GUEST_CS_BASE 06808h +%define VMX_VMCS64_GUEST_SS_BASE 0680Ah +%define VMX_VMCS64_GUEST_DS_BASE 0680Ch +%define VMX_VMCS64_GUEST_FS_BASE 0680Eh +%define VMX_VMCS64_GUEST_GS_BASE 06810h +%define VMX_VMCS64_GUEST_LDTR_BASE 06812h +%define VMX_VMCS64_GUEST_TR_BASE 06814h +%define VMX_VMCS64_GUEST_GDTR_BASE 06816h +%define VMX_VMCS64_GUEST_IDTR_BASE 06818h +%define VMX_VMCS64_GUEST_DR7 0681Ah +%define VMX_VMCS64_GUEST_RSP 0681Ch +%define VMX_VMCS64_GUEST_RIP 0681Eh +%define VMX_VMCS64_GUEST_RFLAGS 06820h +%define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 06822h +%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h +%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h +%define VMX_VMCS_HOST_CR0 06C00h +%define VMX_VMCS_HOST_CR3 06C02h +%define VMX_VMCS_HOST_CR4 06C04h +%define VMX_VMCS_HOST_FS_BASE 06C06h +%define VMX_VMCS_HOST_GS_BASE 06C08h +%define VMX_VMCS_HOST_TR_BASE 06C0Ah +%define VMX_VMCS_HOST_GDTR_BASE 06C0Ch +%define VMX_VMCS_HOST_IDTR_BASE 06C0Eh +%define VMX_VMCS_HOST_SYSENTER_ESP 06C10h +%define VMX_VMCS_HOST_SYSENTER_EIP 06C12h +%define VMX_VMCS_HOST_RSP 06C14h +%define VMX_VMCS_HOST_RIP 06C16h + +%define VMX_RESTORE_HOST_SEL_DS 1h ;RT_BIT(0) +%define VMX_RESTORE_HOST_SEL_ES 2h ;RT_BIT(1) +%define VMX_RESTORE_HOST_SEL_FS 4h ;RT_BIT(2) +%define VMX_RESTORE_HOST_SEL_GS 8h ;RT_BIT(3) +%define VMX_RESTORE_HOST_SEL_TR 10h ;RT_BIT(4) +%define VMX_RESTORE_HOST_GDTR 20h ;RT_BIT(5) +%define VMX_RESTORE_HOST_IDTR 40h ;RT_BIT(6) +%define VMX_RESTORE_HOST_REQUIRED 80h ;RT_BIT(7) + +;; C version hm_vmx.h. +struc VMXRESTOREHOST + .uHostSelDS resw 1 + .uHostSelES resw 1 + .uHostSelFS resw 1 + .uHostSelGS resw 1 + .uHostSelTR resw 1 + .abPadding0 resb 4 + .HostGdtr resb 10 + .abPadding1 resb 6 + .HostIdtr resb 10 + .uHostFSBase resq 1 + .uHostGSBase resq 1 +endstruc +AssertCompileMemberOffset(VMXRESTOREHOST, HostGdtr, 16-2) +AssertCompileMemberOffset(VMXRESTOREHOST, HostIdtr, 32-2) +AssertCompileMemberOffset(VMXRESTOREHOST, uHostFSBase, 40) +AssertCompileSize(VMXRESTOREHOST, 56) + diff --git a/include/VBox/vmm/hwacc_svm.h b/include/VBox/vmm/hwacc_svm.h deleted file mode 100644 index 8912e378..00000000 --- a/include/VBox/vmm/hwacc_svm.h +++ /dev/null @@ -1,744 +0,0 @@ -/** @file - * HWACCM - SVM Structures and Definitions. (VMM) - */ - -/* - * Copyright (C) 2006-2007 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 ___VBox_vmm_svm_h -#define ___VBox_vmm_svm_h - -#include -#include -#include -#include - -/** @defgroup grp_svm svm Types and Definitions - * @ingroup grp_hwaccm - * @{ - */ - -/** @name SVM features for cpuid 0x8000000a - * @{ - */ -/** Bit 0 - NP - Nested Paging supported. */ -#define AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING RT_BIT(0) -/** Bit 1 - LbrVirt - Support for saving five debug MSRs. */ -#define AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT RT_BIT(1) -/** Bit 2 - SVML - SVM locking bit supported. */ -#define AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK RT_BIT(2) -/** Bit 3 - NRIPS - Saving the next instruction pointer is supported. */ -#define AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE RT_BIT(3) -/** Bit 4 - TscRateMsr - Support for MSR TSC ratio. */ -#define AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR RT_BIT(4) -/** Bit 5 - VmcbClean - Support VMCB clean bits. */ -#define AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN RT_BIT(5) -/** Bit 6 - FlushByAsid - Indicate TLB flushing for current ASID only, and that - * VMCB.TLB_Control is supported. */ -#define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID RT_BIT(6) -/** Bit 7 - DecodeAssist - Indicate decode assist is supported. */ -#define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST RT_BIT(7) -/** Where did we get this from? */ -#define AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE RT_BIT(9) -/** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */ -#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER RT_BIT(10) -/** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE - * intercept filter cycle count threshold. */ -#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD RT_BIT(12) -/** @} */ - - -/** @name SVM Basic Exit Reasons. - * @{ - */ -/** Invalid guest state in VMCB. */ -#define SVM_EXIT_INVALID -1 -/** Read from CR0-CR15. */ -#define SVM_EXIT_READ_CR0 0x0 -#define SVM_EXIT_READ_CR1 0x1 -#define SVM_EXIT_READ_CR2 0x2 -#define SVM_EXIT_READ_CR3 0x3 -#define SVM_EXIT_READ_CR4 0x4 -#define SVM_EXIT_READ_CR5 0x5 -#define SVM_EXIT_READ_CR6 0x6 -#define SVM_EXIT_READ_CR7 0x7 -#define SVM_EXIT_READ_CR8 0x8 -#define SVM_EXIT_READ_CR9 0x9 -#define SVM_EXIT_READ_CR10 0xA -#define SVM_EXIT_READ_CR11 0xB -#define SVM_EXIT_READ_CR12 0xC -#define SVM_EXIT_READ_CR13 0xD -#define SVM_EXIT_READ_CR14 0xE -#define SVM_EXIT_READ_CR15 0xF -/** Writes to CR0-CR15. */ -#define SVM_EXIT_WRITE_CR0 0x10 -#define SVM_EXIT_WRITE_CR1 0x11 -#define SVM_EXIT_WRITE_CR2 0x12 -#define SVM_EXIT_WRITE_CR3 0x13 -#define SVM_EXIT_WRITE_CR4 0x14 -#define SVM_EXIT_WRITE_CR5 0x15 -#define SVM_EXIT_WRITE_CR6 0x16 -#define SVM_EXIT_WRITE_CR7 0x17 -#define SVM_EXIT_WRITE_CR8 0x18 -#define SVM_EXIT_WRITE_CR9 0x19 -#define SVM_EXIT_WRITE_CR10 0x1A -#define SVM_EXIT_WRITE_CR11 0x1B -#define SVM_EXIT_WRITE_CR12 0x1C -#define SVM_EXIT_WRITE_CR13 0x1D -#define SVM_EXIT_WRITE_CR14 0x1E -#define SVM_EXIT_WRITE_CR15 0x1F -/** Read from DR0-DR15. */ -#define SVM_EXIT_READ_DR0 0x20 -#define SVM_EXIT_READ_DR1 0x21 -#define SVM_EXIT_READ_DR2 0x22 -#define SVM_EXIT_READ_DR3 0x23 -#define SVM_EXIT_READ_DR4 0x24 -#define SVM_EXIT_READ_DR5 0x25 -#define SVM_EXIT_READ_DR6 0x26 -#define SVM_EXIT_READ_DR7 0x27 -#define SVM_EXIT_READ_DR8 0x28 -#define SVM_EXIT_READ_DR9 0x29 -#define SVM_EXIT_READ_DR10 0x2A -#define SVM_EXIT_READ_DR11 0x2B -#define SVM_EXIT_READ_DR12 0x2C -#define SVM_EXIT_READ_DR13 0x2D -#define SVM_EXIT_READ_DR14 0x2E -#define SVM_EXIT_READ_DR15 0x2F -/** Writes to DR0-DR15. */ -#define SVM_EXIT_WRITE_DR0 0x30 -#define SVM_EXIT_WRITE_DR1 0x31 -#define SVM_EXIT_WRITE_DR2 0x32 -#define SVM_EXIT_WRITE_DR3 0x33 -#define SVM_EXIT_WRITE_DR4 0x34 -#define SVM_EXIT_WRITE_DR5 0x35 -#define SVM_EXIT_WRITE_DR6 0x36 -#define SVM_EXIT_WRITE_DR7 0x37 -#define SVM_EXIT_WRITE_DR8 0x38 -#define SVM_EXIT_WRITE_DR9 0x39 -#define SVM_EXIT_WRITE_DR10 0x3A -#define SVM_EXIT_WRITE_DR11 0x3B -#define SVM_EXIT_WRITE_DR12 0x3C -#define SVM_EXIT_WRITE_DR13 0x3D -#define SVM_EXIT_WRITE_DR14 0x3E -#define SVM_EXIT_WRITE_DR15 0x3F -/* Exception 0-31. */ -#define SVM_EXIT_EXCEPTION_0 0x40 -#define SVM_EXIT_EXCEPTION_1 0x41 -#define SVM_EXIT_EXCEPTION_2 0x42 -#define SVM_EXIT_EXCEPTION_3 0x43 -#define SVM_EXIT_EXCEPTION_4 0x44 -#define SVM_EXIT_EXCEPTION_5 0x45 -#define SVM_EXIT_EXCEPTION_6 0x46 -#define SVM_EXIT_EXCEPTION_7 0x47 -#define SVM_EXIT_EXCEPTION_8 0x48 -#define SVM_EXIT_EXCEPTION_9 0x49 -#define SVM_EXIT_EXCEPTION_A 0x4A -#define SVM_EXIT_EXCEPTION_B 0x4B -#define SVM_EXIT_EXCEPTION_C 0x4C -#define SVM_EXIT_EXCEPTION_D 0x4D -#define SVM_EXIT_EXCEPTION_E 0x4E -#define SVM_EXIT_EXCEPTION_F 0x4F -#define SVM_EXIT_EXCEPTION_10 0x50 -#define SVM_EXIT_EXCEPTION_11 0x51 -#define SVM_EXIT_EXCEPTION_12 0x52 -#define SVM_EXIT_EXCEPTION_13 0x53 -#define SVM_EXIT_EXCEPTION_14 0x54 -#define SVM_EXIT_EXCEPTION_15 0x55 -#define SVM_EXIT_EXCEPTION_16 0x56 -#define SVM_EXIT_EXCEPTION_17 0x57 -#define SVM_EXIT_EXCEPTION_18 0x58 -#define SVM_EXIT_EXCEPTION_19 0x59 -#define SVM_EXIT_EXCEPTION_1A 0x5A -#define SVM_EXIT_EXCEPTION_1B 0x5B -#define SVM_EXIT_EXCEPTION_1C 0x5C -#define SVM_EXIT_EXCEPTION_1D 0x5D -#define SVM_EXIT_EXCEPTION_1E 0x5E -#define SVM_EXIT_EXCEPTION_1F 0x5F -/** Physical maskable interrupt. */ -#define SVM_EXIT_INTR 0x60 -/** Non-maskable interrupt. */ -#define SVM_EXIT_NMI 0x61 -/** System Management interrupt. */ -#define SVM_EXIT_SMI 0x62 -/** Physical INIT signal. */ -#define SVM_EXIT_INIT 0x63 -/** Virtual interrupt. */ -#define SVM_EXIT_VINTR 0x64 -/** Write to CR0 that changed any bits other than CR0.TS or CR0.MP. */ -#define SVM_EXIT_CR0_SEL_WRITE 0x65 -/** IDTR read. */ -#define SVM_EXIT_IDTR_READ 0x66 -/** GDTR read. */ -#define SVM_EXIT_GDTR_READ 0x67 -/** LDTR read. */ -#define SVM_EXIT_LDTR_READ 0x68 -/** TR read. */ -#define SVM_EXIT_TR_READ 0x69 -/** IDTR write. */ -#define SVM_EXIT_IDTR_WRITE 0x6A -/** GDTR write. */ -#define SVM_EXIT_GDTR_WRITE 0x6B -/** LDTR write. */ -#define SVM_EXIT_LDTR_WRITE 0x6C -/** TR write. */ -#define SVM_EXIT_TR_WRITE 0x6D -/** RDTSC instruction. */ -#define SVM_EXIT_RDTSC 0x6E -/** RDPMC instruction. */ -#define SVM_EXIT_RDPMC 0x6F -/** PUSHF instruction. */ -#define SVM_EXIT_PUSHF 0x70 -/** POPF instruction. */ -#define SVM_EXIT_POPF 0x71 -/** CPUID instruction. */ -#define SVM_EXIT_CPUID 0x72 -/** RSM instruction. */ -#define SVM_EXIT_RSM 0x73 -/** IRET instruction. */ -#define SVM_EXIT_IRET 0x74 -/** software interrupt (INTn instructions). */ -#define SVM_EXIT_SWINT 0x75 -/** INVD instruction. */ -#define SVM_EXIT_INVD 0x76 -/** PAUSE instruction. */ -#define SVM_EXIT_PAUSE 0x77 -/** HLT instruction. */ -#define SVM_EXIT_HLT 0x78 -/** INVLPG instructions. */ -#define SVM_EXIT_INVLPG 0x79 -/** INVLPGA instruction. */ -#define SVM_EXIT_INVLPGA 0x7A -/** IN or OUT accessing protected port (the EXITINFO1 field provides more information). */ -#define SVM_EXIT_IOIO 0x7B -/** RDMSR or WRMSR access to protected MSR. */ -#define SVM_EXIT_MSR 0x7C -/** task switch. */ -#define SVM_EXIT_TASK_SWITCH 0x7D -/** FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt. */ -#define SVM_EXIT_FERR_FREEZE 0x7E -/** Shutdown. */ -#define SVM_EXIT_SHUTDOWN 0x7F -/** VMRUN instruction. */ -#define SVM_EXIT_VMRUN 0x80 -/** VMMCALL instruction. */ -#define SVM_EXIT_VMMCALL 0x81 -/** VMLOAD instruction. */ -#define SVM_EXIT_VMLOAD 0x82 -/** VMSAVE instruction. */ -#define SVM_EXIT_VMSAVE 0x83 -/** STGI instruction. */ -#define SVM_EXIT_STGI 0x84 -/** CLGI instruction. */ -#define SVM_EXIT_CLGI 0x85 -/** SKINIT instruction. */ -#define SVM_EXIT_SKINIT 0x86 -/** RDTSCP instruction. */ -#define SVM_EXIT_RDTSCP 0x87 -/** ICEBP instruction. */ -#define SVM_EXIT_ICEBP 0x88 -/** WBINVD instruction. */ -#define SVM_EXIT_WBINVD 0x89 -/** MONITOR instruction. */ -#define SVM_EXIT_MONITOR 0x8A -/** MWAIT instruction uncond. */ -#define SVM_EXIT_MWAIT_UNCOND 0x8B -/** MWAIT instruction when armed. */ -#define SVM_EXIT_MWAIT_ARMED 0x8C -/** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */ -#define SVM_EXIT_NPF 0x400 - -/** @} */ - - -/** @name SVM_VMCB.u64ExitInfo2 - * @{ - */ -/** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */ -#define SVM_EXIT2_TASK_SWITCH_IRET RT_BIT_64(36) -/** Set to 1 if the task switch was caused by a far jump; else cleared to 0. */ -#define SVM_EXIT2_TASK_SWITCH_JMP RT_BIT_64(38) -/** Set to 1 if the task switch has an error code; else cleared to 0. */ -#define SVM_EXIT2_TASK_SWITCH_HAS_ERROR_CODE RT_BIT_64(44) -/** The value of EFLAGS.RF that would be saved in the outgoing TSS if the task switch were not intercepted. */ -#define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF RT_BIT_64(48) -/** @} */ - -/** @name SVM_VMCB.ctrl.u32InterceptCtrl1 - * @{ - */ -/** 0 Intercept INTR (physical maskable interrupt). */ -#define SVM_CTRL1_INTERCEPT_INTR RT_BIT(0) -/** 1 Intercept NMI. */ -#define SVM_CTRL1_INTERCEPT_NMI RT_BIT(1) -/** 2 Intercept SMI. */ -#define SVM_CTRL1_INTERCEPT_SMI RT_BIT(2) -/** 3 Intercept INIT. */ -#define SVM_CTRL1_INTERCEPT_INIT RT_BIT(3) -/** 4 Intercept VINTR (virtual maskable interrupt). */ -#define SVM_CTRL1_INTERCEPT_VINTR RT_BIT(4) -/** 5 Intercept CR0 writes that change bits other than CR0.TS or CR0.MP */ -#define SVM_CTRL1_INTERCEPT_CR0 RT_BIT(5) -/** 6 Intercept reads of IDTR. */ -#define SVM_CTRL1_INTERCEPT_IDTR_READS RT_BIT(6) -/** 7 Intercept reads of GDTR. */ -#define SVM_CTRL1_INTERCEPT_GDTR_READS RT_BIT(7) -/** 8 Intercept reads of LDTR. */ -#define SVM_CTRL1_INTERCEPT_LDTR_READS RT_BIT(8) -/** 9 Intercept reads of TR. */ -#define SVM_CTRL1_INTERCEPT_TR_READS RT_BIT(9) -/** 10 Intercept writes of IDTR. */ -#define SVM_CTRL1_INTERCEPT_IDTR_WRITES RT_BIT(10) -/** 11 Intercept writes of GDTR. */ -#define SVM_CTRL1_INTERCEPT_GDTR_WRITES RT_BIT(11) -/** 12 Intercept writes of LDTR. */ -#define SVM_CTRL1_INTERCEPT_LDTR_WRITES RT_BIT(12) -/** 13 Intercept writes of TR. */ -#define SVM_CTRL1_INTERCEPT_TR_WRITES RT_BIT(13) -/** 14 Intercept RDTSC instruction. */ -#define SVM_CTRL1_INTERCEPT_RDTSC RT_BIT(14) -/** 15 Intercept RDPMC instruction. */ -#define SVM_CTRL1_INTERCEPT_RDPMC RT_BIT(15) -/** 16 Intercept PUSHF instruction. */ -#define SVM_CTRL1_INTERCEPT_PUSHF RT_BIT(16) -/** 17 Intercept POPF instruction. */ -#define SVM_CTRL1_INTERCEPT_POPF RT_BIT(17) -/** 18 Intercept CPUID instruction. */ -#define SVM_CTRL1_INTERCEPT_CPUID RT_BIT(18) -/** 19 Intercept RSM instruction. */ -#define SVM_CTRL1_INTERCEPT_RSM RT_BIT(19) -/** 20 Intercept IRET instruction. */ -#define SVM_CTRL1_INTERCEPT_IRET RT_BIT(20) -/** 21 Intercept INTn instruction. */ -#define SVM_CTRL1_INTERCEPT_INTN RT_BIT(21) -/** 22 Intercept INVD instruction. */ -#define SVM_CTRL1_INTERCEPT_INVD RT_BIT(22) -/** 23 Intercept PAUSE instruction. */ -#define SVM_CTRL1_INTERCEPT_PAUSE RT_BIT(23) -/** 24 Intercept HLT instruction. */ -#define SVM_CTRL1_INTERCEPT_HLT RT_BIT(24) -/** 25 Intercept INVLPG instruction. */ -#define SVM_CTRL1_INTERCEPT_INVLPG RT_BIT(25) -/** 26 Intercept INVLPGA instruction. */ -#define SVM_CTRL1_INTERCEPT_INVLPGA RT_BIT(26) -/** 27 IOIO_PROT Intercept IN/OUT accesses to selected ports. */ -#define SVM_CTRL1_INTERCEPT_INOUT_BITMAP RT_BIT(27) -/** 28 MSR_PROT Intercept RDMSR or WRMSR accesses to selected MSRs. */ -#define SVM_CTRL1_INTERCEPT_MSR_SHADOW RT_BIT(28) -/** 29 Intercept task switches. */ -#define SVM_CTRL1_INTERCEPT_TASK_SWITCH RT_BIT(29) -/** 30 FERR_FREEZE: intercept processor "freezing" during legacy FERR handling. */ -#define SVM_CTRL1_INTERCEPT_FERR_FREEZE RT_BIT(30) -/** 31 Intercept shutdown events. */ -#define SVM_CTRL1_INTERCEPT_SHUTDOWN RT_BIT(31) -/** @} */ - - -/** @name SVM_VMCB.ctrl.u32InterceptCtrl2 - * @{ - */ -/** 0 Intercept VMRUN instruction. */ -#define SVM_CTRL2_INTERCEPT_VMRUN RT_BIT(0) -/** 1 Intercept VMMCALL instruction. */ -#define SVM_CTRL2_INTERCEPT_VMMCALL RT_BIT(1) -/** 2 Intercept VMLOAD instruction. */ -#define SVM_CTRL2_INTERCEPT_VMLOAD RT_BIT(2) -/** 3 Intercept VMSAVE instruction. */ -#define SVM_CTRL2_INTERCEPT_VMSAVE RT_BIT(3) -/** 4 Intercept STGI instruction. */ -#define SVM_CTRL2_INTERCEPT_STGI RT_BIT(4) -/** 5 Intercept CLGI instruction. */ -#define SVM_CTRL2_INTERCEPT_CLGI RT_BIT(5) -/** 6 Intercept SKINIT instruction. */ -#define SVM_CTRL2_INTERCEPT_SKINIT RT_BIT(6) -/** 7 Intercept RDTSCP instruction. */ -#define SVM_CTRL2_INTERCEPT_RDTSCP RT_BIT(7) -/** 8 Intercept ICEBP instruction. */ -#define SVM_CTRL2_INTERCEPT_ICEBP RT_BIT(8) -/** 9 Intercept WBINVD instruction. */ -#define SVM_CTRL2_INTERCEPT_WBINVD RT_BIT(9) -/** 10 Intercept MONITOR instruction. */ -#define SVM_CTRL2_INTERCEPT_MONITOR RT_BIT(10) -/** 11 Intercept MWAIT instruction unconditionally. */ -#define SVM_CTRL2_INTERCEPT_MWAIT_UNCOND RT_BIT(11) -/** 12 Intercept MWAIT instruction when armed. */ -#define SVM_CTRL2_INTERCEPT_MWAIT_ARMED RT_BIT(12) -/** 13 Intercept XSETBV instruction. */ -#define SVM_CTRL2_INTERCEPT_XSETBV RT_BIT(13) -/** @} */ - -/** @name SVM_VMCB.ctrl.u64NestedPaging - * @{ - */ -#define SVM_NESTED_PAGING_ENABLE RT_BIT(0) -/** @} */ - -/** @name SVM_VMCB.ctrl.u64IntShadow - * @{ - */ -#define SVM_INTERRUPT_SHADOW_ACTIVE RT_BIT(0) -/** @} */ - - -/** @name SVM_INTCTRL.u3Type - * @{ - */ -/** External or virtual interrupt. */ -#define SVM_EVENT_EXTERNAL_IRQ 0 -/** Non-maskable interrupt. */ -#define SVM_EVENT_NMI 2 -/** Exception; fault or trap. */ -#define SVM_EVENT_EXCEPTION 3 -/** Software interrupt. */ -#define SVM_EVENT_SOFTWARE_INT 4 -/** @} */ - - -/** @name SVM_VMCB.ctrl.TLBCtrl.n.u8TLBFlush - * @{ - */ -/** Flush nothing. */ -#define SVM_TLB_FLUSH_NOTHING 0 -/** Flush entire TLB (host+guest entries) */ -#define SVM_TLB_FLUSH_ENTIRE 1 -/** Flush this guest's TLB entries (by ASID) */ -#define SVM_TLB_FLUSH_SINGLE_CONTEXT 3 -/** Flush this guest's non-global TLB entries (by ASID) */ -#define SVM_TLB_FLUSH_SINGLE_CONTEXT_RETAIN_GLOBALS 7 -/** @} */ - - -/** - * SVM Selector type; includes hidden parts. - */ -#pragma pack(1) -typedef struct -{ - uint16_t u16Sel; - uint16_t u16Attr; - uint32_t u32Limit; - uint64_t u64Base; /**< Only lower 32 bits are implemented for CS, DS, ES & SS. */ -} SVMSEL; -#pragma pack() - -/** - * SVM GDTR/IDTR type. - */ -#pragma pack(1) -typedef struct -{ - uint16_t u16Reserved1; - uint16_t u16Reserved2; - uint32_t u32Limit; /**< Only lower 16 bits are implemented. */ - uint64_t u64Base; -} SVMGDTR; -#pragma pack() - -typedef SVMGDTR SVMIDTR; - -/** - * SVM Event injection structure. - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t u8Vector : 8; - uint32_t u3Type : 3; - uint32_t u1ErrorCodeValid : 1; - uint32_t u19Reserved : 19; - uint32_t u1Valid : 1; - uint32_t u32ErrorCode : 32; - } n; - uint64_t au64[1]; -} SVM_EVENT; -#pragma pack() - - -/** - * SVM Interrupt control structure. - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t u8VTPR : 8; - uint32_t u1VIrqValid : 1; - uint32_t u7Reserved : 7; - uint32_t u4VIrqPriority : 4; - uint32_t u1IgnoreTPR : 1; - uint32_t u3Reserved : 3; - uint32_t u1VIrqMasking : 1; - uint32_t u7Reserved2 : 7; - uint32_t u8VIrqVector : 8; - uint32_t u24Reserved : 24; - } n; - uint64_t au64[1]; -} SVM_INTCTRL; -#pragma pack() - - -/** - * SVM TLB control structure. - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t u32ASID : 32; - uint32_t u8TLBFlush : 8; - uint32_t u24Reserved : 24; - } n; - uint64_t au64[1]; -} SVM_TLBCTRL; -#pragma pack() - - -/** - * SVM IOIO exit structure. - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t u1Type : 1; /**< 0 = out, 1 = in */ - uint32_t u1Reserved : 1; - uint32_t u1STR : 1; - uint32_t u1REP : 1; - uint32_t u1OP8 : 1; - uint32_t u1OP16 : 1; - uint32_t u1OP32 : 1; - uint32_t u1ADDR16 : 1; - uint32_t u1ADDR32 : 1; - uint32_t u1ADDR64 : 1; - uint32_t u6Reserved : 6; - uint32_t u16Port : 16; - } n; - uint32_t au32[1]; -} SVM_IOIO_EXIT; -#pragma pack() - -/** - * SVM nested paging structure. - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t u1NestedPaging : 1; /**< enabled/disabled */ - } n; - uint64_t au64[1]; -} SVM_NPCTRL; -#pragma pack() - -/** - * SVM VM Control Block. (VMCB) - */ -#pragma pack(1) -typedef struct _SVM_VMCB -{ - /** Control Area. */ - struct - { - /** Offset 0x00 - Intercept reads of CR0-15. */ - uint16_t u16InterceptRdCRx; - /** Offset 0x02 - Intercept writes to CR0-15. */ - uint16_t u16InterceptWrCRx; - /** Offset 0x04 - Intercept reads of DR0-15. */ - uint16_t u16InterceptRdDRx; - /** Offset 0x06 - Intercept writes to DR0-15. */ - uint16_t u16InterceptWrDRx; - /** Offset 0x08 - Intercept exception vectors 0-31. */ - uint32_t u32InterceptException; - /** Offset 0x0C - Intercept control field 1. */ - uint32_t u32InterceptCtrl1; - /** Offset 0x0C - Intercept control field 2. */ - uint32_t u32InterceptCtrl2; - /** Offset 0x14-0x3F - Reserved. */ - uint8_t u8Reserved[0x3e - 0x14]; - /** Offset 0x3e - PAUSE intercept filter count. */ - uint16_t u16PauseFilterCount; - /** Offset 0x40 - Physical address of IOPM. */ - uint64_t u64IOPMPhysAddr; - /** Offset 0x48 - Physical address of MSRPM. */ - uint64_t u64MSRPMPhysAddr; - /** Offset 0x50 - TSC Offset. */ - uint64_t u64TSCOffset; - /** Offset 0x58 - TLB control field. */ - SVM_TLBCTRL TLBCtrl; - /** Offset 0x60 - Interrupt control field. */ - SVM_INTCTRL IntCtrl; - /** Offset 0x68 - Interrupt shadow. */ - uint64_t u64IntShadow; - /** Offset 0x70 - Exit code. */ - uint64_t u64ExitCode; - /** Offset 0x78 - Exit info 1. */ - uint64_t u64ExitInfo1; - /** Offset 0x80 - Exit info 2. */ - uint64_t u64ExitInfo2; - /** Offset 0x88 - Exit Interrupt info. */ - SVM_EVENT ExitIntInfo; - /** Offset 0x90 - Nested Paging. */ - SVM_NPCTRL NestedPaging; - /** Offset 0x98-0xA7 - Reserved. */ - uint8_t u8Reserved2[0xA8-0x98]; - /** Offset 0xA8 - Event injection. */ - SVM_EVENT EventInject; - /** Offset 0xB0 - Host CR3 for nested paging. */ - uint64_t u64NestedPagingCR3; - /** Offset 0xB8 - LBR Virtualization. */ - uint64_t u64LBRVirt; - /** Offset 0xC0 - VMCB Clean Bits. */ - uint64_t u64VMCBCleanBits; - /** Offset 0xC8 - Next sequential instruction pointer. */ - uint64_t u64NextRIP; - /** Offset 0xD0 - Number of bytes fetched. */ - uint8_t cbInstrFetched; - /** Offset 0xD1 - Number of bytes fetched. */ - uint8_t abInstr[15]; - } ctrl; - - /** Offset 0xC0-0x3FF - Reserved. */ - uint8_t u8Reserved3[0x400-0xE0]; - - /** State Save Area. Starts at offset 0x400. */ - struct - { - /** Offset 0x400 - Guest ES register + hidden parts. */ - SVMSEL ES; - /** Offset 0x410 - Guest CS register + hidden parts. */ - SVMSEL CS; - /** Offset 0x420 - Guest SS register + hidden parts. */ - SVMSEL SS; - /** Offset 0x430 - Guest DS register + hidden parts. */ - SVMSEL DS; - /** Offset 0x440 - Guest FS register + hidden parts. */ - SVMSEL FS; - /** Offset 0x450 - Guest GS register + hidden parts. */ - SVMSEL GS; - /** Offset 0x460 - Guest GDTR register. */ - SVMGDTR GDTR; - /** Offset 0x470 - Guest LDTR register + hidden parts. */ - SVMSEL LDTR; - /** Offset 0x480 - Guest IDTR register. */ - SVMIDTR IDTR; - /** Offset 0x490 - Guest TR register + hidden parts. */ - SVMSEL TR; - /** Offset 0x4A0-0x4CA - Reserved. */ - uint8_t u8Reserved4[0x4CB-0x4A0]; - /** Offset 0x4CB - CPL. */ - uint8_t u8CPL; - /** Offset 0x4CC-0x4CF - Reserved. */ - uint8_t u8Reserved5[0x4D0-0x4CC]; - /** Offset 0x4D0 - EFER. */ - uint64_t u64EFER; - /** Offset 0x4D8-0x547 - Reserved. */ - uint8_t u8Reserved6[0x548-0x4D8]; - /** Offset 0x548 - CR4. */ - uint64_t u64CR4; - /** Offset 0x550 - CR3. */ - uint64_t u64CR3; - /** Offset 0x558 - CR0. */ - uint64_t u64CR0; - /** Offset 0x560 - DR7. */ - uint64_t u64DR7; - /** Offset 0x568 - DR6. */ - uint64_t u64DR6; - /** Offset 0x570 - RFLAGS. */ - uint64_t u64RFlags; - /** Offset 0x578 - RIP. */ - uint64_t u64RIP; - /** Offset 0x580-0x5D7 - Reserved. */ - uint8_t u8Reserved7[0x5D8-0x580]; - /** Offset 0x5D8 - RSP. */ - uint64_t u64RSP; - /** Offset 0x5E0-0x5F7 - Reserved. */ - uint8_t u8Reserved8[0x5F8-0x5E0]; - /** Offset 0x5F8 - RAX. */ - uint64_t u64RAX; - /** Offset 0x600 - STAR. */ - uint64_t u64STAR; - /** Offset 0x608 - LSTAR. */ - uint64_t u64LSTAR; - /** Offset 0x610 - CSTAR. */ - uint64_t u64CSTAR; - /** Offset 0x618 - SFMASK. */ - uint64_t u64SFMASK; - /** Offset 0x620 - KernelGSBase. */ - uint64_t u64KernelGSBase; - /** Offset 0x628 - SYSENTER_CS. */ - uint64_t u64SysEnterCS; - /** Offset 0x630 - SYSENTER_ESP. */ - uint64_t u64SysEnterESP; - /** Offset 0x638 - SYSENTER_EIP. */ - uint64_t u64SysEnterEIP; - /** Offset 0x640 - CR2. */ - uint64_t u64CR2; - /** Offset 0x648-0x667 - Reserved. */ - uint8_t u8Reserved9[0x668-0x648]; - /** Offset 0x668 - G_PAT. */ - uint64_t u64GPAT; - /** Offset 0x670 - DBGCTL. */ - uint64_t u64DBGCTL; - /** Offset 0x678 - BR_FROM. */ - uint64_t u64BR_FROM; - /** Offset 0x680 - BR_TO. */ - uint64_t u64BR_TO; - /** Offset 0x688 - LASTEXCPFROM. */ - uint64_t u64LASTEXCPFROM; - /** Offset 0x690 - LASTEXCPTO. */ - uint64_t u64LASTEXCPTO; - } guest; - - /** Offset 0x698-0xFFF- Reserved. */ - uint8_t u8Reserved10[0x1000-0x698]; -} SVM_VMCB; -#pragma pack() -AssertCompileSize(SVM_VMCB, 0x1000); -AssertCompileMemberOffset(SVM_VMCB, ctrl.u16InterceptRdCRx, 0x000); -AssertCompileMemberOffset(SVM_VMCB, ctrl.u16PauseFilterCount,0x03e); -AssertCompileMemberOffset(SVM_VMCB, ctrl.TLBCtrl, 0x058); -AssertCompileMemberOffset(SVM_VMCB, ctrl.ExitIntInfo, 0x088); -AssertCompileMemberOffset(SVM_VMCB, ctrl.EventInject, 0x0A8); -AssertCompileMemberOffset(SVM_VMCB, ctrl.abInstr, 0x0D1); -AssertCompileMemberOffset(SVM_VMCB, guest, 0x400); -AssertCompileMemberOffset(SVM_VMCB, guest.ES, 0x400); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved4, 0x4A0); -AssertCompileMemberOffset(SVM_VMCB, guest.u8CPL, 0x4CB); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved6, 0x4D8); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved7, 0x580); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved9, 0x648); -AssertCompileMemberOffset(SVM_VMCB, guest.u64GPAT, 0x668); -AssertCompileMemberOffset(SVM_VMCB, guest.u64LASTEXCPTO, 0x690); -AssertCompileMemberOffset(SVM_VMCB, u8Reserved10, 0x698); - -#ifdef IN_RING0 -VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); -#endif /* IN_RING0 */ - -/** @} */ - -#endif - diff --git a/include/VBox/vmm/hwacc_vmx.h b/include/VBox/vmm/hwacc_vmx.h deleted file mode 100644 index a96f587e..00000000 --- a/include/VBox/vmm/hwacc_vmx.h +++ /dev/null @@ -1,1708 +0,0 @@ -/** @file - * HWACCM - VMX Structures and Definitions. (VMM) - */ - -/* - * 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; - * 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 ___VBox_vmm_vmx_h -#define ___VBox_vmm_vmx_h - -#include -#include -#include -#include - -/** @defgroup grp_vmx vmx Types and Definitions - * @ingroup grp_hwaccm - * @{ - */ - -/** @name VMX EPT paging structures - * @{ - */ - -/** - * Number of page table entries in the EPT. (PDPTE/PDE/PTE) - */ -#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES - -/** - * EPT Page Directory Pointer Entry. Bit view. - * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC, - * this did cause trouble with one compiler/version). - */ -#pragma pack(1) -typedef struct EPTPML4EBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** Reserved (must be 0). */ - uint64_t u5Reserved : 5; - /** Available for software. */ - uint64_t u4Available : 4; - /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPML4EBITS; -#pragma pack() -AssertCompileSize(EPTPML4EBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK -/** The page shift to get the PML4 index. */ -#define EPT_PML4_SHIFT X86_PML4_SHIFT -/** The PML4 index mask (apply to a shifted page address). */ -#define EPT_PML4_MASK X86_PML4_MASK - -/** - * EPT PML4E. - */ -#pragma pack(1) -typedef union EPTPML4E -{ - /** Normal view. */ - EPTPML4EBITS n; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPML4E; -#pragma pack() -/** Pointer to a PML4 table entry. */ -typedef EPTPML4E *PEPTPML4E; -/** Pointer to a const PML4 table entry. */ -typedef const EPTPML4E *PCEPTPML4E; -AssertCompileSize(EPTPML4E, 8); - -/** - * EPT PML4 Table. - */ -#pragma pack(1) -typedef struct EPTPML4 -{ - EPTPML4E a[EPT_PG_ENTRIES]; -} EPTPML4; -#pragma pack() -/** Pointer to an EPT PML4 Table. */ -typedef EPTPML4 *PEPTPML4; -/** Pointer to a const EPT PML4 Table. */ -typedef const EPTPML4 *PCEPTPML4; - -/** - * EPT Page Directory Pointer Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPDPTEBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** Reserved (must be 0). */ - uint64_t u5Reserved : 5; - /** Available for software. */ - uint64_t u4Available : 4; - /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPDPTEBITS; -#pragma pack() -AssertCompileSize(EPTPDPTEBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK -/** The page shift to get the PDPT index. */ -#define EPT_PDPT_SHIFT X86_PDPT_SHIFT -/** The PDPT index mask (apply to a shifted page address). */ -#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64 - -/** - * EPT Page Directory Pointer. - */ -#pragma pack(1) -typedef union EPTPDPTE -{ - /** Normal view. */ - EPTPDPTEBITS n; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPDPTE; -#pragma pack() -/** Pointer to an EPT Page Directory Pointer Entry. */ -typedef EPTPDPTE *PEPTPDPTE; -/** Pointer to a const EPT Page Directory Pointer Entry. */ -typedef const EPTPDPTE *PCEPTPDPTE; -AssertCompileSize(EPTPDPTE, 8); - -/** - * EPT Page Directory Pointer Table. - */ -#pragma pack(1) -typedef struct EPTPDPT -{ - EPTPDPTE a[EPT_PG_ENTRIES]; -} EPTPDPT; -#pragma pack() -/** Pointer to an EPT Page Directory Pointer Table. */ -typedef EPTPDPT *PEPTPDPT; -/** Pointer to a const EPT Page Directory Pointer Table. */ -typedef const EPTPDPT *PCEPTPDPT; - - -/** - * EPT Page Directory Table Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPDEBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** Reserved (must be 0). */ - uint64_t u4Reserved : 4; - /** Big page (must be 0 here). */ - uint64_t u1Size : 1; - /** Available for software. */ - uint64_t u4Available : 4; - /** Physical address of page table. Restricted by maximum physical address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPDEBITS; -#pragma pack() -AssertCompileSize(EPTPDEBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK -/** The page shift to get the PD index. */ -#define EPT_PD_SHIFT X86_PD_PAE_SHIFT -/** The PD index mask (apply to a shifted page address). */ -#define EPT_PD_MASK X86_PD_PAE_MASK - -/** - * EPT 2MB Page Directory Table Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPDE2MBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** EPT Table Memory Type. MBZ for non-leaf nodes. */ - uint64_t u3EMT : 3; - /** Ignore PAT memory type */ - uint64_t u1IgnorePAT : 1; - /** Big page (must be 1 here). */ - uint64_t u1Size : 1; - /** Available for software. */ - uint64_t u4Available : 4; - /** Reserved (must be 0). */ - uint64_t u9Reserved : 9; - /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */ - uint64_t u31PhysAddr : 31; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPDE2MBITS; -#pragma pack() -AssertCompileSize(EPTPDE2MBITS, 8); - -/** Bits 21-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK - -/** - * EPT Page Directory Table Entry. - */ -#pragma pack(1) -typedef union EPTPDE -{ - /** Normal view. */ - EPTPDEBITS n; - /** 2MB view (big). */ - EPTPDE2MBITS b; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPDE; -#pragma pack() -/** Pointer to an EPT Page Directory Table Entry. */ -typedef EPTPDE *PEPTPDE; -/** Pointer to a const EPT Page Directory Table Entry. */ -typedef const EPTPDE *PCEPTPDE; -AssertCompileSize(EPTPDE, 8); - -/** - * EPT Page Directory Table. - */ -#pragma pack(1) -typedef struct EPTPD -{ - EPTPDE a[EPT_PG_ENTRIES]; -} EPTPD; -#pragma pack() -/** Pointer to an EPT Page Directory Table. */ -typedef EPTPD *PEPTPD; -/** Pointer to a const EPT Page Directory Table. */ -typedef const EPTPD *PCEPTPD; - - -/** - * EPT Page Table Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPTEBITS -{ - /** 0 - Present bit. - * @remark This is a convenience "misnomer". The bit actually indicates - * read access and the CPU will consider an entry with any of the - * first three bits set as present. Since all our valid entries - * will have this bit set, it can be used as a present indicator - * and allow some code sharing. */ - uint64_t u1Present : 1; - /** 1 - Writable bit. */ - uint64_t u1Write : 1; - /** 2 - Executable bit. */ - uint64_t u1Execute : 1; - /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */ - uint64_t u3EMT : 3; - /** 6 - Ignore PAT memory type */ - uint64_t u1IgnorePAT : 1; - /** 11:7 - Available for software. */ - uint64_t u5Available : 5; - /** 51:12 - Physical address of page. Restricted by maximum physical - * address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** 63:52 - Available for software. */ - uint64_t u12Available : 12; -} EPTPTEBITS; -#pragma pack() -AssertCompileSize(EPTPTEBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK -/** The page shift to get the EPT PTE index. */ -#define EPT_PT_SHIFT X86_PT_PAE_SHIFT -/** The EPT PT index mask (apply to a shifted page address). */ -#define EPT_PT_MASK X86_PT_PAE_MASK - -/** - * EPT Page Table Entry. - */ -#pragma pack(1) -typedef union EPTPTE -{ - /** Normal view. */ - EPTPTEBITS n; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPTE; -#pragma pack() -/** Pointer to an EPT Page Directory Table Entry. */ -typedef EPTPTE *PEPTPTE; -/** Pointer to a const EPT Page Directory Table Entry. */ -typedef const EPTPTE *PCEPTPTE; -AssertCompileSize(EPTPTE, 8); - -/** - * EPT Page Table. - */ -#pragma pack(1) -typedef struct EPTPT -{ - EPTPTE a[EPT_PG_ENTRIES]; -} EPTPT; -#pragma pack() -/** Pointer to an extended page table. */ -typedef EPTPT *PEPTPT; -/** Pointer to a const extended table. */ -typedef const EPTPT *PCEPTPT; - -/** - * VPID flush types. - */ -typedef enum -{ - /** Invalidate a specific page. */ - VMX_FLUSH_VPID_INDIV_ADDR = 0, - /** Invalidate one context (specific VPID). */ - VMX_FLUSH_VPID_SINGLE_CONTEXT = 1, - /** Invalidate all contexts (all VPIDs). */ - VMX_FLUSH_VPID_ALL_CONTEXTS = 2, - /** Invalidate a single VPID context retaining global mappings. */ - VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3, - /** Unsupported by VirtualBox. */ - VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad, - /** Unsupported by CPU. */ - VMX_FLUSH_VPID_NONE = 0xb00, - /** 32bit hackishness. */ - VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff -} VMX_FLUSH_VPID; - -/** - * EPT flush types. - */ -typedef enum -{ - /** Invalidate one context (specific EPT). */ - VMX_FLUSH_EPT_SINGLE_CONTEXT = 1, - /* Invalidate all contexts (all EPTs) */ - VMX_FLUSH_EPT_ALL_CONTEXTS = 2, - /** Unsupported by VirtualBox. */ - VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad, - /** Unsupported by CPU. */ - VMX_FLUSH_EPT_NONE = 0xb00, - /** 32bit hackishness. */ - VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff -} VMX_FLUSH_EPT; -/** @} */ - -/** @name MSR load/store elements - * @{ - */ -#pragma pack(1) -typedef struct -{ - uint32_t u32IndexMSR; - uint32_t u32Reserved; - uint64_t u64Value; -} VMXMSR; -#pragma pack() -/** Pointer to an MSR load/store element. */ -typedef VMXMSR *PVMXMSR; -/** Pointer to a const MSR load/store element. */ -typedef const VMXMSR *PCVMXMSR; - -/** @} */ - - -/** @name VT-x capability qword - * @{ - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t disallowed0; - uint32_t allowed1; - } n; - uint64_t u; -} VMX_CAPABILITY; -#pragma pack() -/** @} */ - -/** @name VMX Basic Exit Reasons. - * @{ - */ -/** And-mask for setting reserved bits to zero */ -#define VMX_EFLAGS_RESERVED_0 (~0xffc08028) -/** Or-mask for setting reserved bits to 1 */ -#define VMX_EFLAGS_RESERVED_1 0x00000002 -/** @} */ - -/** @name VMX Basic Exit Reasons. - * @{ - */ -/** -1 Invalid exit code */ -#define VMX_EXIT_INVALID -1 -/** 0 Exception or non-maskable interrupt (NMI). */ -#define VMX_EXIT_EXCEPTION 0 -/** 1 External interrupt. */ -#define VMX_EXIT_EXTERNAL_IRQ 1 -/** 2 Triple fault. */ -#define VMX_EXIT_TRIPLE_FAULT 2 -/** 3 INIT signal. */ -#define VMX_EXIT_INIT_SIGNAL 3 -/** 4 Start-up IPI (SIPI). */ -#define VMX_EXIT_SIPI 4 -/** 5 I/O system-management interrupt (SMI). */ -#define VMX_EXIT_IO_SMI_IRQ 5 -/** 6 Other SMI. */ -#define VMX_EXIT_SMI_IRQ 6 -/** 7 Interrupt window. */ -#define VMX_EXIT_IRQ_WINDOW 7 -/** 9 Task switch. */ -#define VMX_EXIT_TASK_SWITCH 9 -/** 10 Guest software attempted to execute CPUID. */ -#define VMX_EXIT_CPUID 10 -/** 12 Guest software attempted to execute HLT. */ -#define VMX_EXIT_HLT 12 -/** 13 Guest software attempted to execute INVD. */ -#define VMX_EXIT_INVD 13 -/** 14 Guest software attempted to execute INVLPG. */ -#define VMX_EXIT_INVLPG 14 -/** 15 Guest software attempted to execute RDPMC. */ -#define VMX_EXIT_RDPMC 15 -/** 16 Guest software attempted to execute RDTSC. */ -#define VMX_EXIT_RDTSC 16 -/** 17 Guest software attempted to execute RSM in SMM. */ -#define VMX_EXIT_RSM 17 -/** 18 Guest software executed VMCALL. */ -#define VMX_EXIT_VMCALL 18 -/** 19 Guest software executed VMCLEAR. */ -#define VMX_EXIT_VMCLEAR 19 -/** 20 Guest software executed VMLAUNCH. */ -#define VMX_EXIT_VMLAUNCH 20 -/** 21 Guest software executed VMPTRLD. */ -#define VMX_EXIT_VMPTRLD 21 -/** 22 Guest software executed VMPTRST. */ -#define VMX_EXIT_VMPTRST 22 -/** 23 Guest software executed VMREAD. */ -#define VMX_EXIT_VMREAD 23 -/** 24 Guest software executed VMRESUME. */ -#define VMX_EXIT_VMRESUME 24 -/** 25 Guest software executed VMWRITE. */ -#define VMX_EXIT_VMWRITE 25 -/** 26 Guest software executed VMXOFF. */ -#define VMX_EXIT_VMXOFF 26 -/** 27 Guest software executed VMXON. */ -#define VMX_EXIT_VMXON 27 -/** 28 Control-register accesses. */ -#define VMX_EXIT_CRX_MOVE 28 -/** 29 Debug-register accesses. */ -#define VMX_EXIT_DRX_MOVE 29 -/** 30 I/O instruction. */ -#define VMX_EXIT_PORT_IO 30 -/** 31 RDMSR. Guest software attempted to execute RDMSR. */ -#define VMX_EXIT_RDMSR 31 -/** 32 WRMSR. Guest software attempted to execute WRMSR. */ -#define VMX_EXIT_WRMSR 32 -/** 33 VM-entry failure due to invalid guest state. */ -#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33 -/** 34 VM-entry failure due to MSR loading. */ -#define VMX_EXIT_ERR_MSR_LOAD 34 -/** 36 Guest software executed MWAIT. */ -#define VMX_EXIT_MWAIT 36 -/** 37 VM exit due to monitor trap flag. */ -#define VMX_EXIT_MTF 37 -/** 39 Guest software attempted to execute MONITOR. */ -#define VMX_EXIT_MONITOR 39 -/** 40 Guest software attempted to execute PAUSE. */ -#define VMX_EXIT_PAUSE 40 -/** 41 VM-entry failure due to machine-check. */ -#define VMX_EXIT_ERR_MACHINE_CHECK 41 -/** 43 TPR below threshold. Guest software executed MOV to CR8. */ -#define VMX_EXIT_TPR 43 -/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */ -#define VMX_EXIT_APIC_ACCESS 44 -/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */ -#define VMX_EXIT_XDTR_ACCESS 46 -/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */ -#define VMX_EXIT_TR_ACCESS 47 -/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */ -#define VMX_EXIT_EPT_VIOLATION 48 -/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */ -#define VMX_EXIT_EPT_MISCONFIG 49 -/** 50 INVEPT. Guest software attempted to execute INVEPT. */ -#define VMX_EXIT_INVEPT 50 -/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */ -#define VMX_EXIT_RDTSCP 51 -/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */ -#define VMX_EXIT_PREEMPTION_TIMER 52 -/** 53 INVVPID. Guest software attempted to execute INVVPID. */ -#define VMX_EXIT_INVVPID 53 -/** 54 WBINVD. Guest software attempted to execute WBINVD. */ -#define VMX_EXIT_WBINVD 54 -/** 55 XSETBV. Guest software attempted to execute XSETBV. */ -#define VMX_EXIT_XSETBV 55 -/** @} */ - - -/** @name VM Instruction Errors - * @{ - */ -/** 1 VMCALL executed in VMX root operation. */ -#define VMX_ERROR_VMCALL 1 -/** 2 VMCLEAR with invalid physical address. */ -#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2 -/** 3 VMCLEAR with VMXON pointer. */ -#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3 -/** 4 VMLAUNCH with non-clear VMCS. */ -#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4 -/** 5 VMRESUME with non-launched VMCS. */ -#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5 -/** 6 VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */ -#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6 -/** 7 VM entry with invalid control field(s). */ -#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7 -/** 8 VM entry with invalid host-state field(s). */ -#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8 -/** 9 VMPTRLD with invalid physical address. */ -#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9 -/** 10 VMPTRLD with VMXON pointer. */ -#define VMX_ERROR_VMPTRLD_VMXON_PTR 10 -/** 11 VMPTRLD with incorrect VMCS revision identifier. */ -#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11 -/** 12 VMREAD/VMWRITE from/to unsupported VMCS component. */ -#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12 -#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT -/** 13 VMWRITE to read-only VMCS component. */ -#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13 -/** 15 VMXON executed in VMX root operation. */ -#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15 -/** 16 VM entry with invalid executive-VMCS pointer. */ -#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16 -/** 17 VM entry with non-launched executive VMCS. */ -#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17 -/** 18 VM entry with executive-VMCS pointer not VMXON pointer. */ -#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18 -/** 19 VMCALL with non-clear VMCS. */ -#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19 -/** 20 VMCALL with invalid VM-exit control fields. */ -#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20 -/** 22 VMCALL with incorrect MSEG revision identifier. */ -#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22 -/** 23 VMXOFF under dual-monitor treatment of SMIs and SMM. */ -#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23 -/** 24 VMCALL with invalid SMM-monitor features. */ -#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24 -/** 25 VM entry with invalid VM-execution control fields in executive VMCS. */ -#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25 -/** 26 VM entry with events blocked by MOV SS. */ -#define VMX_ERROR_VMENTRY_MOV_SS 26 -/** 26 Invalid operand to INVEPT/INVVPID. */ -#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28 - -/** @} */ - - -/** @name VMX MSRs - Basic VMX information. - * @{ - */ -/** VMCS revision identifier used by the processor. */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) (a & 0x7FFFFFFF) -/** Size of the VMCS. */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0xFFF) -/** Width of physical address used for the VMCS. - * 0 -> limited to the available amount of physical ram - * 1 -> within the first 4 GB - */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1) -/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1) -/** Memory type that must be used for the VMCS. */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF) -/** @} */ - - -/** @name VMX MSRs - Misc VMX info. - * @{ - */ -/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */ -#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f) -/** Activity states supported by the implementation. */ -#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7) -/** Number of CR3 target values supported by the processor. (0-256) */ -#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF) -/** Maximum nr of MSRs in the VMCS. (N+1)*512. */ -#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512) -/** MSEG revision identifier used by the processor. */ -#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32) -/** @} */ - - -/** @name VMX MSRs - VMCS enumeration field info - * @{ - */ -/** Highest field index. */ -#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF) - -/** @} */ - - -/** @name MSR_IA32_VMX_EPT_CAPS; EPT capabilities MSR - * @{ - */ -#define MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY RT_BIT_64(0) -#define MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY RT_BIT_64(1) -#define MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY RT_BIT_64(2) -#define MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS RT_BIT_64(3) -#define MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS RT_BIT_64(4) -#define MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS RT_BIT_64(5) -#define MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS RT_BIT_64(6) -#define MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS RT_BIT_64(7) -#define MSR_IA32_VMX_EPT_CAPS_EMT_UC RT_BIT_64(8) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WC RT_BIT_64(9) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WT RT_BIT_64(12) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WP RT_BIT_64(13) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WB RT_BIT_64(14) -#define MSR_IA32_VMX_EPT_CAPS_SP_21_BITS RT_BIT_64(16) -#define MSR_IA32_VMX_EPT_CAPS_SP_30_BITS RT_BIT_64(17) -#define MSR_IA32_VMX_EPT_CAPS_SP_39_BITS RT_BIT_64(18) -#define MSR_IA32_VMX_EPT_CAPS_SP_48_BITS RT_BIT_64(19) -#define MSR_IA32_VMX_EPT_CAPS_INVEPT RT_BIT_64(20) -#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT RT_BIT_64(25) -#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS RT_BIT_64(26) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID RT_BIT_64(32) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR RT_BIT_64(40) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT RT_BIT_64(41) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS RT_BIT_64(42) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43) - -/** @} */ - -/** @name Extended Page Table Pointer (EPTP) - * @{ - */ -/** Uncachable EPT paging structure memory type. */ -#define VMX_EPT_MEMTYPE_UC 0 -/** Write-back EPT paging structure memory type. */ -#define VMX_EPT_MEMTYPE_WB 6 -/** Shift value to get the EPT page walk length (bits 5-3) */ -#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3 -/** Mask value to get the EPT page walk length (bits 5-3) */ -#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7 -/** Default EPT page walk length */ -#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3 -/** @} */ - - -/** @name VMCS field encoding - 16 bits guest fields - * @{ - */ -#define VMX_VMCS16_GUEST_FIELD_VPID 0x0 -#define VMX_VMCS16_GUEST_FIELD_ES 0x800 -#define VMX_VMCS16_GUEST_FIELD_CS 0x802 -#define VMX_VMCS16_GUEST_FIELD_SS 0x804 -#define VMX_VMCS16_GUEST_FIELD_DS 0x806 -#define VMX_VMCS16_GUEST_FIELD_FS 0x808 -#define VMX_VMCS16_GUEST_FIELD_GS 0x80A -#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C -#define VMX_VMCS16_GUEST_FIELD_TR 0x80E -/** @} */ - -/** @name VMCS field encoding - 16 bits host fields - * @{ - */ -#define VMX_VMCS16_HOST_FIELD_ES 0xC00 -#define VMX_VMCS16_HOST_FIELD_CS 0xC02 -#define VMX_VMCS16_HOST_FIELD_SS 0xC04 -#define VMX_VMCS16_HOST_FIELD_DS 0xC06 -#define VMX_VMCS16_HOST_FIELD_FS 0xC08 -#define VMX_VMCS16_HOST_FIELD_GS 0xC0A -#define VMX_VMCS16_HOST_FIELD_TR 0xC0C -/** @} */ - -/** @name VMCS field encoding - 64 bits host fields - * @{ - */ -#define VMX_VMCS_HOST_FIELD_PAT_FULL 0x2C00 -#define VMX_VMCS_HOST_FIELD_PAT_HIGH 0x2C01 -#define VMX_VMCS_HOST_FIELD_EFER_FULL 0x2C02 -#define VMX_VMCS_HOST_FIELD_EFER_HIGH 0x2C03 -#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */ -#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */ -/** @} */ - - -/** @name VMCS field encoding - 64 Bits control fields - * @{ - */ -#define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 0x2000 -#define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 0x2001 -#define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 0x2002 -#define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 0x2003 - -/* Optional */ -#define VMX_VMCS_CTRL_MSR_BITMAP_FULL 0x2004 -#define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 0x2005 - -#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 0x2006 -#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 0x2007 -#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 0x2008 -#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 0x2009 - -#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0x200A -#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0x200B - -#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0x200C -#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0x200D - -#define VMX_VMCS_CTRL_TSC_OFFSET_FULL 0x2010 -#define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 0x2011 - -/** Optional (VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW) */ -#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 0x2012 -#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 0x2013 - -/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */ -#define VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL 0x2014 -#define VMX_VMCS_CTRL_APIC_ACCESSADDR_HIGH 0x2015 - -/** Extended page table pointer. */ -#define VMX_VMCS_CTRL_EPTP_FULL 0x201a -#define VMX_VMCS_CTRL_EPTP_HIGH 0x201b - -/** VM-exit phyiscal address. */ -#define VMX_VMCS_EXIT_PHYS_ADDR_FULL 0x2400 -#define VMX_VMCS_EXIT_PHYS_ADDR_HIGH 0x2401 -/** @} */ - - -/** @name VMCS field encoding - 64 Bits guest fields - * @{ - */ -#define VMX_VMCS_GUEST_LINK_PTR_FULL 0x2800 -#define VMX_VMCS_GUEST_LINK_PTR_HIGH 0x2801 -#define VMX_VMCS_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */ -#define VMX_VMCS_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */ -#define VMX_VMCS_GUEST_PAT_FULL 0x2804 -#define VMX_VMCS_GUEST_PAT_HIGH 0x2805 -#define VMX_VMCS_GUEST_EFER_FULL 0x2806 -#define VMX_VMCS_GUEST_EFER_HIGH 0x2807 -#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */ -#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */ -#define VMX_VMCS_GUEST_PDPTR0_FULL 0x280A -#define VMX_VMCS_GUEST_PDPTR0_HIGH 0x280B -#define VMX_VMCS_GUEST_PDPTR1_FULL 0x280C -#define VMX_VMCS_GUEST_PDPTR1_HIGH 0x280D -#define VMX_VMCS_GUEST_PDPTR2_FULL 0x280E -#define VMX_VMCS_GUEST_PDPTR2_HIGH 0x280F -#define VMX_VMCS_GUEST_PDPTR3_FULL 0x2810 -#define VMX_VMCS_GUEST_PDPTR3_HIGH 0x2811 -/** @} */ - - -/** @name VMCS field encoding - 32 Bits control fields - * @{ - */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 0x4000 -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 0x4002 -#define VMX_VMCS_CTRL_EXCEPTION_BITMAP 0x4004 -#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 0x4006 -#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 0x4008 -#define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0x400A -#define VMX_VMCS_CTRL_EXIT_CONTROLS 0x400C -#define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0x400E -#define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 0x4010 -#define VMX_VMCS_CTRL_ENTRY_CONTROLS 0x4012 -#define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014 -#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 0x4016 -#define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018 -#define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0x401A -/** This field exists only on processors that support the 1-setting of the “use TPR shadow” VM-execution control. */ -#define VMX_VMCS_CTRL_TPR_THRESHOLD 0x401C -/** This field exists only on processors that support the 1-setting of the “activate secondary controls” VM-execution control. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 0x401E -/** @} */ - - -/** @name VMX_VMCS_CTRL_PIN_EXEC_CONTROLS - * @{ - */ -/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT RT_BIT(0) -/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT RT_BIT(3) -/** Virtual NMIs. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI RT_BIT(5) -/** Activate VMX preemption timer. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER RT_BIT(6) -/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */ -/** @} */ - -/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS - * @{ - */ -/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT RT_BIT(2) -/** Use timestamp counter offset. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET RT_BIT(3) -/** VM Exit when executing the HLT instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT RT_BIT(7) -/** VM Exit when executing the INVLPG instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT RT_BIT(9) -/** VM Exit when executing the MWAIT instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT RT_BIT(10) -/** VM Exit when executing the RDPMC instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT RT_BIT(11) -/** VM Exit when executing the RDTSC/RDTSCP instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT RT_BIT(12) -/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT RT_BIT(15) -/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT RT_BIT(16) -/** VM Exit on CR8 loads. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT RT_BIT(19) -/** VM Exit on CR8 stores. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT RT_BIT(20) -/** Use TPR shadow. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW RT_BIT(21) -/** VM Exit when virtual nmi blocking is disabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT RT_BIT(22) -/** VM Exit when executing a MOV DRx instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT RT_BIT(23) -/** VM Exit when executing IO instructions. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT RT_BIT(24) -/** Use IO bitmaps. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS RT_BIT(25) -/** Monitor trap flag. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG RT_BIT(27) -/** Use MSR bitmaps. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS RT_BIT(28) -/** VM Exit when executing the MONITOR instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT RT_BIT(29) -/** VM Exit when executing the PAUSE instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT RT_BIT(30) -/** Determines whether the secondary processor based VM-execution controls are used. */ -#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31) -/** @} */ - -/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 - * @{ - */ -/** Virtualize APIC access. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0) -/** EPT supported/enabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1) -/** Descriptor table instructions cause VM-exits. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT RT_BIT(2) -/** RDTSCP supported/enabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3) -/** Virtualize x2APIC mode. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_X2APIC RT_BIT(4) -/** VPID supported/enabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5) -/** VM Exit when executing the WBINVD instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6) -/** Unrestricted guest execution. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE RT_BIT(7) -/** A specified nr of pause loops cause a VM-exit. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10) -/** @} */ - - -/** @name VMX_VMCS_CTRL_ENTRY_CONTROLS - * @{ - */ -/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG RT_BIT(2) -/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE RT_BIT(9) -/** In SMM mode after VM-entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM RT_BIT(10) -/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON RT_BIT(11) -/** This control determines whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR RT_BIT(13) -/** This control determines whether the guest IA32_PAT MSR is loaded on VM entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR RT_BIT(14) -/** This control determines whether the guest IA32_EFER MSR is loaded on VM entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR RT_BIT(15) -/** @} */ - - -/** @name VMX_VMCS_CTRL_EXIT_CONTROLS - * @{ - */ -/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG RT_BIT(2) -/** Return to long mode after a VM-exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9) -/** This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_PERF_MSR RT_BIT(12) -/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ RT_BIT(15) -/** This control determines whether the guest IA32_PAT MSR is saved on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR RT_BIT(18) -/** This control determines whether the host IA32_PAT MSR is loaded on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR RT_BIT(19) -/** This control determines whether the guest IA32_EFER MSR is saved on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR RT_BIT(20) -/** This control determines whether the host IA32_EFER MSR is loaded on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR RT_BIT(21) -/** This control determines whether the value of the VMX preemption timer is saved on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER RT_BIT(22) -/** @} */ - -/** @name VMCS field encoding - 32 Bits read-only fields - * @{ - */ -#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400 -#define VMX_VMCS32_RO_EXIT_REASON 0x4402 -#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404 -#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE 0x4406 -#define VMX_VMCS32_RO_IDT_INFO 0x4408 -#define VMX_VMCS32_RO_IDT_ERRCODE 0x440A -#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C -#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E -/** @} */ - -/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO - * @{ - */ -#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) (a & 0xff) -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7) -#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11) -#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID) -#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) (a & RT_BIT(12)) -#define VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT 31 -#define VMX_EXIT_INTERRUPTION_INFO_VALID(a) (a & RT_BIT(31)) -/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */ -#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) (a & ~RT_BIT(12)) -/** @} */ - -/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE - * @{ - */ -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT 0 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT 3 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW 4 /**< int xx */ -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_DBEXCPT 5 /**< Why are we getting this one?? */ -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT 6 -/** @} */ - - -/** @name VMCS field encoding - 32 Bits guest state fields - * @{ - */ -#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800 -#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802 -#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804 -#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806 -#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808 -#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A -#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C -#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E -#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810 -#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812 -#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814 -#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816 -#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818 -#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A -#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C -#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E -#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820 -#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822 -#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824 -#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826 -#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */ -#define VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE 0x482E -/** @} */ - - -/** @name VMX_VMCS_GUEST_ACTIVITY_STATE - * @{ - */ -/** The logical processor is active. */ -#define VMX_CMS_GUEST_ACTIVITY_ACTIVE 0x0 -/** The logical processor is inactive, because executed a HLT instruction. */ -#define VMX_CMS_GUEST_ACTIVITY_HLT 0x1 -/** The logical processor is inactive, because of a triple fault or other serious error. */ -#define VMX_CMS_GUEST_ACTIVITY_SHUTDOWN 0x2 -/** The logical processor is inactive, because it's waiting for a startup-IPI */ -#define VMX_CMS_GUEST_ACTIVITY_SIPI_WAIT 0x3 -/** @} */ - - -/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE - * @{ - */ -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0) -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1) -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2) -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3) -/** @} */ - - -/** @name VMCS field encoding - 32 Bits host state fields - * @{ - */ -#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00 -/** @} */ - -/** @name Natural width control fields - * @{ - */ -#define VMX_VMCS_CTRL_CR0_MASK 0x6000 -#define VMX_VMCS_CTRL_CR4_MASK 0x6002 -#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004 -#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006 -#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008 -#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A -#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C -#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E -/** @} */ - - -/** @name Natural width read-only data fields - * @{ - */ -#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400 -#define VMX_VMCS_RO_IO_RCX 0x6402 -#define VMX_VMCS_RO_IO_RSX 0x6404 -#define VMX_VMCS_RO_IO_RDI 0x6406 -#define VMX_VMCS_RO_IO_RIP 0x6408 -#define VMX_VMCS_EXIT_GUEST_LINEAR_ADDR 0x640A -/** @} */ - - -/** @name VMX_VMCS_RO_EXIT_QUALIFICATION - * @{ - */ -/** 0-2: Debug register number */ -#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) (a & 7) -/** 3: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) ((a >> 3) & 1) -/** 4: Direction of move (0 = write, 1 = read) */ -#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) ((a >> 4) & 1) -/** 5-7: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) ((a >> 5) & 7) -/** 8-11: General purpose register number. */ -#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) ((a >> 8) & 0xF) -/** Rest: reserved. */ -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values - * @{ - */ -#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0 -#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1 -/** @} */ - - - -/** @name CRx accesses - * @{ - */ -/** 0-3: Control register number (0 for CLTS & LMSW) */ -#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) (a & 0xF) -/** 4-5: Access type. */ -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) ((a >> 4) & 3) -/** 6: LMSW operand type */ -#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) ((a >> 6) & 1) -/** 7: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) ((a >> 7) & 1) -/** 8-11: General purpose register number (0 for CLTS & LMSW). */ -#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) ((a >> 8) & 0xF) -/** 12-15: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) ((a >> 12) & 0xF) -/** 16-31: LMSW source data (else 0). */ -#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) ((a >> 16) & 0xFFFF) -/** Rest: reserved. */ -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS - * @{ - */ -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0 -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1 -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2 -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3 -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH - * @{ - */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) (a & 0xffff) -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) ((a >> 30)& 0x3) -/** Task switch caused by a call instruction. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0 -/** Task switch caused by an iret instruction. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1 -/** Task switch caused by a jmp instruction. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2 -/** Task switch caused by an interrupt gate. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3 - -/** @} */ - - -/** @name VMX_EXIT_EPT_VIOLATION - * @{ - */ -/** Set if the violation was caused by a data read. */ -#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0) -/** Set if the violation was caused by a data write. */ -#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1) -/** Set if the violation was caused by an insruction fetch. */ -#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2) -/** AND of the present bit of all EPT structures. */ -#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3) -/** AND of the write bit of all EPT structures. */ -#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4) -/** AND of the execute bit of all EPT structures. */ -#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5) -/** Set if the guest linear address field contains the faulting address. */ -#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7) -/** If bit 7 is one: (reserved otherwise) - * 1 - violation due to physical address access. - * 0 - violation caused by page walk or access/dirty bit updates - */ -#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8) -/** @} */ - - -/** @name VMX_EXIT_PORT_IO - * @{ - */ -/** 0-2: IO operation width. */ -#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) (a & 7) -/** 3: IO operation direction. */ -#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) ((a >> 3) & 1) -/** 4: String IO operation. */ -#define VMX_EXIT_QUALIFICATION_IO_STRING(a) ((a >> 4) & 1) -/** 5: Repeated IO operation. */ -#define VMX_EXIT_QUALIFICATION_IO_REP(a) ((a >> 5) & 1) -/** 6: Operand encoding. */ -#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) ((a >> 6) & 1) -/** 16-31: IO Port (0-0xffff). */ -#define VMX_EXIT_QUALIFICATION_IO_PORT(a) ((a >> 16) & 0xffff) -/* Rest reserved. */ -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION - * @{ - */ -#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0 -#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1 -/** @} */ - - -/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING - * @{ - */ -#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0 -#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1 -/** @} */ - -/** @name VMX_EXIT_APIC_ACCESS - * @{ - */ -/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */ -#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) (a & 0xfff) -/** 12-15: Access type. */ -#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a >> 12) & 0xf) -/* Rest reserved. */ -/** @} */ - - -/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types - * @{ - */ -/** Linear read access. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0 -/** Linear write access. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1 -/** Linear instruction fetch access. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2 -/** Linear read/write access during event delivery. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3 -/** Physical read/write access during event delivery. */ -#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10 -/** Physical access for an instruction fetch or during instruction execution. */ -#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15 -/** @} */ - -/** @} */ - -/** @name VMCS field encoding - Natural width guest state fields - * @{ - */ -#define VMX_VMCS64_GUEST_CR0 0x6800 -#define VMX_VMCS64_GUEST_CR3 0x6802 -#define VMX_VMCS64_GUEST_CR4 0x6804 -#define VMX_VMCS64_GUEST_ES_BASE 0x6806 -#define VMX_VMCS64_GUEST_CS_BASE 0x6808 -#define VMX_VMCS64_GUEST_SS_BASE 0x680A -#define VMX_VMCS64_GUEST_DS_BASE 0x680C -#define VMX_VMCS64_GUEST_FS_BASE 0x680E -#define VMX_VMCS64_GUEST_GS_BASE 0x6810 -#define VMX_VMCS64_GUEST_LDTR_BASE 0x6812 -#define VMX_VMCS64_GUEST_TR_BASE 0x6814 -#define VMX_VMCS64_GUEST_GDTR_BASE 0x6816 -#define VMX_VMCS64_GUEST_IDTR_BASE 0x6818 -#define VMX_VMCS64_GUEST_DR7 0x681A -#define VMX_VMCS64_GUEST_RSP 0x681C -#define VMX_VMCS64_GUEST_RIP 0x681E -#define VMX_VMCS_GUEST_RFLAGS 0x6820 -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 0x6822 -#define VMX_VMCS64_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */ -#define VMX_VMCS64_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */ -/** @} */ - - -/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS - * @{ - */ -/** Hardware breakpoint 0 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0) -/** Hardware breakpoint 1 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1) -/** Hardware breakpoint 2 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2) -/** Hardware breakpoint 3 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3) -/** At least one data or IO breakpoint was hit. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12) -/** A debug exception would have been triggered by single-step execution mode. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14) -/** Bits 4-11, 13 and 15-63 are reserved. */ - -/** @} */ - -/** @name VMCS field encoding - Natural width host state fields - * @{ - */ -#define VMX_VMCS_HOST_CR0 0x6C00 -#define VMX_VMCS_HOST_CR3 0x6C02 -#define VMX_VMCS_HOST_CR4 0x6C04 -#define VMX_VMCS_HOST_FS_BASE 0x6C06 -#define VMX_VMCS_HOST_GS_BASE 0x6C08 -#define VMX_VMCS_HOST_TR_BASE 0x6C0A -#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C -#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E -#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10 -#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12 -#define VMX_VMCS_HOST_RSP 0x6C14 -#define VMX_VMCS_HOST_RIP 0x6C16 -/** @} */ - -/** @} */ - - -#if RT_INLINE_ASM_GNU_STYLE -# define __STR(x) #x -# define STR(x) __STR(x) -#endif - - -/** @defgroup grp_vmx_asm vmx assembly helpers - * @ingroup grp_vmx - * @{ - */ - -/** - * Executes VMXON - * - * @returns VBox status code - * @param pVMXOn Physical address of VMXON structure - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXEnable(RTHCPHYS pVMXOn); -#else -DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "push %3 \n\t" - "push %2 \n\t" - ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t" - "ja 2f \n\t" - "je 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t" - "jmp 2f \n\t" - "1: \n\t" - "movl $"STR(VERR_VMX_GENERIC)", %0 \n\t" - "2: \n\t" - "add $8, %%esp \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */ - "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */ - :"memory" - ); -# else - __asm - { - push dword ptr [pVMXOn+4] - push dword ptr [pVMXOn] - _emit 0xF3 - _emit 0x0F - _emit 0xC7 - _emit 0x34 - _emit 0x24 /* VMXON [esp] */ - jnc vmxon_good - mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR - jmp the_end - -vmxon_good: - jnz the_end - mov dword ptr [rc], VERR_VMX_GENERIC -the_end: - add esp, 8 - } -# endif - return rc; -} -#endif - - -/** - * Executes VMXOFF - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(void) VMXDisable(void); -#else -DECLINLINE(void) VMXDisable(void) -{ -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t" - ); -# else - __asm - { - _emit 0x0F - _emit 0x01 - _emit 0xC4 /* VMXOFF */ - } -# endif -} -#endif - - -/** - * Executes VMCLEAR - * - * @returns VBox status code - * @param pVMCS Physical address of VM control structure - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS); -#else -DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "push %3 \n\t" - "push %2 \n\t" - ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t" - "jnc 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "1: \n\t" - "add $8, %%esp \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ - "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */ - :"memory" - ); -# else - __asm - { - push dword ptr [pVMCS+4] - push dword ptr [pVMCS] - _emit 0x66 - _emit 0x0F - _emit 0xC7 - _emit 0x34 - _emit 0x24 /* VMCLEAR [esp] */ - jnc success - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR -success: - add esp, 8 - } -# endif - return rc; -} -#endif - - -/** - * Executes VMPTRLD - * - * @returns VBox status code - * @param pVMCS Physical address of VMCS structure - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS); -#else -DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "push %3 \n\t" - "push %2 \n\t" - ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t" - "jnc 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "1: \n\t" - "add $8, %%esp \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ - "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */ - ); -# else - __asm - { - push dword ptr [pVMCS+4] - push dword ptr [pVMCS] - _emit 0x0F - _emit 0xC7 - _emit 0x34 - _emit 0x24 /* VMPTRLD [esp] */ - jnc success - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR - -success: - add esp, 8 - } -# endif - return rc; -} -#endif - -/** - * Executes VMPTRST - * - * @returns VBox status code - * @param pVMCS Address that will receive the current pointer - */ -DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS); - -/** - * Executes VMWRITE - * - * @returns VBox status code - * @param idxField VMCS index - * @param u32Val 32 bits value - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val); -#else -DECLINLINE(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t" - "ja 2f \n\t" - "je 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "jmp 2f \n\t" - "1: \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" - "2: \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "a"(idxField), - "d"(u32Val) - ); -# else - __asm - { - push dword ptr [u32Val] - mov eax, [idxField] - _emit 0x0F - _emit 0x79 - _emit 0x04 - _emit 0x24 /* VMWRITE eax, [esp] */ - jnc valid_vmcs - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR - jmp the_end - -valid_vmcs: - jnz the_end - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD -the_end: - add esp, 4 - } -# endif - return rc; -} -#endif - -/** - * Executes VMWRITE - * - * @returns VBox status code - * @param idxField VMCS index - * @param u64Val 16, 32 or 64 bits value - */ -#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXWriteVMCS64(uint32_t idxField, uint64_t u64Val); -#else -VMMR0DECL(int) VMXWriteVMCS64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val); - -#define VMXWriteVMCS64(idxField, u64Val) VMXWriteVMCS64Ex(pVCpu, idxField, u64Val) -#endif - -#if HC_ARCH_BITS == 64 -#define VMXWriteVMCS VMXWriteVMCS64 -#else -#define VMXWriteVMCS VMXWriteVMCS32 -#endif /* HC_ARCH_BITS == 64 */ - - -/** - * Invalidate a page using invept - * @returns VBox status code - * @param enmFlush Type of flush - * @param pDescriptor Descriptor - */ -DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor); - -/** - * Invalidate a page using invvpid - * @returns VBox status code - * @param enmFlush Type of flush - * @param pDescriptor Descriptor - */ -DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor); - -/** - * Executes VMREAD - * - * @returns VBox status code - * @param idxField VMCS index - * @param pData Ptr to store VM field value - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData); -#else -DECLINLINE(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "movl $"STR(VINF_SUCCESS)", %0 \n\t" - ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t" - "ja 2f \n\t" - "je 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "jmp 2f \n\t" - "1: \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" - "2: \n\t" - :"=&r"(rc), - "=d"(*pData) - :"a"(idxField), - "d"(0) - ); -# else - __asm - { - sub esp, 4 - mov dword ptr [esp], 0 - mov eax, [idxField] - _emit 0x0F - _emit 0x78 - _emit 0x04 - _emit 0x24 /* VMREAD eax, [esp] */ - mov edx, pData - pop dword ptr [edx] - jnc valid_vmcs - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR - jmp the_end - -valid_vmcs: - jnz the_end - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD -the_end: - } -# endif - return rc; -} -#endif - -/** - * Executes VMREAD - * - * @returns VBox status code - * @param idxField VMCS index - * @param pData Ptr to store VM field value - */ -#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData); -#else -DECLINLINE(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData) -{ - int rc; - - uint32_t val_hi, val; - rc = VMXReadVMCS32(idxField, &val); - rc |= VMXReadVMCS32(idxField + 1, &val_hi); - AssertRC(rc); - *pData = RT_MAKE_U64(val, val_hi); - return rc; -} -#endif - -#if HC_ARCH_BITS == 64 -# define VMXReadVMCS VMXReadVMCS64 -#else -# define VMXReadVMCS VMXReadVMCS32 -#endif /* HC_ARCH_BITS == 64 */ - -/** - * Gets the last instruction error value from the current VMCS - * - * @returns error value - */ -DECLINLINE(uint32_t) VMXGetLastError(void) -{ -#if HC_ARCH_BITS == 64 - uint64_t uLastError = 0; - int rc = VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); - AssertRC(rc); - return (uint32_t)uLastError; - -#else /* 32-bit host: */ - uint32_t uLastError = 0; - int rc = VMXReadVMCS32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); - AssertRC(rc); - return uLastError; -#endif -} - -#ifdef IN_RING0 -VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); -VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys); -#endif /* IN_RING0 */ - -/** @} */ - -#endif - diff --git a/include/VBox/vmm/hwacc_vmx.mac b/include/VBox/vmm/hwacc_vmx.mac deleted file mode 100644 index 3fc11b43..00000000 --- a/include/VBox/vmm/hwacc_vmx.mac +++ /dev/null @@ -1,154 +0,0 @@ -;; @file -; HWACCM - VMX Structures and Definitions. -; - -; -; 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; -; 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. -; - -%define VMX_VMCS_GUEST_FIELD_ES 0800h -%define VMX_VMCS_GUEST_FIELD_CS 0802h -%define VMX_VMCS_GUEST_FIELD_SS 0804h -%define VMX_VMCS_GUEST_FIELD_DS 0806h -%define VMX_VMCS_GUEST_FIELD_FS 0808h -%define VMX_VMCS_GUEST_FIELD_GS 080Ah -%define VMX_VMCS_GUEST_FIELD_LDTR 080Ch -%define VMX_VMCS_GUEST_FIELD_TR 080Eh -%define VMX_VMCS_HOST_FIELD_ES 0C00h -%define VMX_VMCS_HOST_FIELD_CS 0C02h -%define VMX_VMCS_HOST_FIELD_SS 0C04h -%define VMX_VMCS_HOST_FIELD_DS 0C06h -%define VMX_VMCS_HOST_FIELD_FS 0C08h -%define VMX_VMCS_HOST_FIELD_GS 0C0Ah -%define VMX_VMCS_HOST_FIELD_TR 0C0Ch -%define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 02000h -%define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 02001h -%define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 02002h -%define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 02003h -%define VMX_VMCS_CTRL_MSR_BITMAP_FULL 02004h -%define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 02005h -%define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 02006h -%define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 02007h -%define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 02008h -%define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 02009h -%define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0200Ah -%define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0200Bh -%define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0200Ch -%define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0200Dh -%define VMX_VMCS_CTRL_TSC_OFFSET_FULL 02010h -%define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 02011h -%define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 02012h -%define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 02013h -%define VMX_VMCS_GUEST_LINK_PTR_FULL 02800h -%define VMX_VMCS_GUEST_LINK_PTR_HIGH 02801h -%define VMX_VMCS_GUEST_DEBUGCTL_FULL 02802h -%define VMX_VMCS_GUEST_DEBUGCTL_HIGH 02803h -%define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 04000h -%define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 04002h -%define VMX_VMCS_CTRL_EXCEPTION_BITMAP 04004h -%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 04006h -%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 04008h -%define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0400Ah -%define VMX_VMCS_CTRL_EXIT_CONTROLS 0400Ch -%define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0400Eh -%define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 04010h -%define VMX_VMCS_CTRL_ENTRY_CONTROLS 04012h -%define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 04014h -%define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 04016h -%define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 04018h -%define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0401Ah -%define VMX_VMCS_CTRL_TRP_TRESHOLD 0401Ch -%define VMX_VMCS_RO_VM_INSTR_ERROR 04400h -%define VMX_VMCS_RO_EXIT_REASON 04402h -%define VMX_VMCS_RO_EXIT_INTERRUPTION_INFO 04404h -%define VMX_VMCS_RO_EXIT_INTERRUPTION_ERRCODE 04406h -%define VMX_VMCS_RO_IDT_INFO 04408h -%define VMX_VMCS_RO_IDT_ERRCODE 0440Ah -%define VMX_VMCS_RO_EXIT_INSTR_LENGTH 0440Ch -%define VMX_VMCS_RO_EXIT_INSTR_INFO 0440Eh -%define VMX_VMCS_GUEST_ES_LIMIT 04800h -%define VMX_VMCS_GUEST_CS_LIMIT 04802h -%define VMX_VMCS_GUEST_SS_LIMIT 04804h -%define VMX_VMCS_GUEST_DS_LIMIT 04806h -%define VMX_VMCS_GUEST_FS_LIMIT 04808h -%define VMX_VMCS_GUEST_GS_LIMIT 0480Ah -%define VMX_VMCS_GUEST_LDTR_LIMIT 0480Ch -%define VMX_VMCS_GUEST_TR_LIMIT 0480Eh -%define VMX_VMCS_GUEST_GDTR_LIMIT 04810h -%define VMX_VMCS_GUEST_IDTR_LIMIT 04812h -%define VMX_VMCS_GUEST_ES_ACCESS_RIGHTS 04814h -%define VMX_VMCS_GUEST_CS_ACCESS_RIGHTS 04816h -%define VMX_VMCS_GUEST_SS_ACCESS_RIGHTS 04818h -%define VMX_VMCS_GUEST_DS_ACCESS_RIGHTS 0481Ah -%define VMX_VMCS_GUEST_FS_ACCESS_RIGHTS 0481Ch -%define VMX_VMCS_GUEST_GS_ACCESS_RIGHTS 0481Eh -%define VMX_VMCS_GUEST_LDTR_ACCESS_RIGHTS 04820h -%define VMX_VMCS_GUEST_TR_ACCESS_RIGHTS 04822h -%define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE 04824h -%define VMX_VMCS_GUEST_ACTIVITY_STATE 04826h -%define VMX_VMCS_GUEST_SYSENTER_CS 0482Ah -%define VMX_VMCS_CTRL_CR0_MASK 06000h -%define VMX_VMCS_CTRL_CR4_MASK 06002h -%define VMX_VMCS_CTRL_CR0_READ_SHADOW 06004h -%define VMX_VMCS_CTRL_CR4_READ_SHADOW 06006h -%define VMX_VMCS_CTRL_CR3_TARGET_VAL0 06008h -%define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0600Ah -%define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0600Ch -%define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0600Eh -%define VMX_VMCS_RO_EXIT_QUALIFICATION 06400h -%define VMX_VMCS_RO_IO_RCX 06402h -%define VMX_VMCS_RO_IO_RSX 06404h -%define VMX_VMCS_RO_IO_RDI 06406h -%define VMX_VMCS_RO_IO_RIP 06408h -%define VMX_VMCS_GUEST_LINEAR_ADDR 0640Ah -%define VMX_VMCS64_GUEST_CR0 06800h -%define VMX_VMCS64_GUEST_CR3 06802h -%define VMX_VMCS64_GUEST_CR4 06804h -%define VMX_VMCS64_GUEST_ES_BASE 06806h -%define VMX_VMCS64_GUEST_CS_BASE 06808h -%define VMX_VMCS64_GUEST_SS_BASE 0680Ah -%define VMX_VMCS64_GUEST_DS_BASE 0680Ch -%define VMX_VMCS64_GUEST_FS_BASE 0680Eh -%define VMX_VMCS64_GUEST_GS_BASE 06810h -%define VMX_VMCS64_GUEST_LDTR_BASE 06812h -%define VMX_VMCS64_GUEST_TR_BASE 06814h -%define VMX_VMCS64_GUEST_GDTR_BASE 06816h -%define VMX_VMCS64_GUEST_IDTR_BASE 06818h -%define VMX_VMCS64_GUEST_DR7 0681Ah -%define VMX_VMCS64_GUEST_RSP 0681Ch -%define VMX_VMCS64_GUEST_RIP 0681Eh -%define VMX_VMCS64_GUEST_RFLAGS 06820h -%define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 06822h -%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h -%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h -%define VMX_VMCS_HOST_CR0 06C00h -%define VMX_VMCS_HOST_CR3 06C02h -%define VMX_VMCS_HOST_CR4 06C04h -%define VMX_VMCS_HOST_FS_BASE 06C06h -%define VMX_VMCS_HOST_GS_BASE 06C08h -%define VMX_VMCS_HOST_TR_BASE 06C0Ah -%define VMX_VMCS_HOST_GDTR_BASE 06C0Ch -%define VMX_VMCS_HOST_IDTR_BASE 06C0Eh -%define VMX_VMCS_HOST_SYSENTER_ESP 06C10h -%define VMX_VMCS_HOST_SYSENTER_EIP 06C12h -%define VMX_VMCS_HOST_RSP 06C14h -%define VMX_VMCS_HOST_RIP 06C16h - -%define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9) diff --git a/include/VBox/vmm/hwaccm.h b/include/VBox/vmm/hwaccm.h deleted file mode 100644 index 98a7d02e..00000000 --- a/include/VBox/vmm/hwaccm.h +++ /dev/null @@ -1,154 +0,0 @@ -/** @file - * HWACCM - Intel/AMD VM Hardware Support Manager (VMM) - */ - -/* - * 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; - * 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 ___VBox_vmm_hwaccm_h -#define ___VBox_vmm_hwaccm_h - -#include -#include -#include - - -/** @defgroup grp_hwaccm The VM Hardware Manager API - * @{ - */ - -RT_C_DECLS_BEGIN - -/** - * Query HWACCM state (enabled/disabled) - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -#define HWACCMIsEnabled(pVM) ((pVM)->fHWACCMEnabled) - - /** - * Check if the current CPU state is valid for emulating IO blocks in the recompiler - * - * @returns boolean - * @param pCtx CPU context - */ -#define HWACCMCanEmulateIoBlock(pVCpu) (!CPUMIsGuestInPagedProtectedMode(pVCpu)) -#define HWACCMCanEmulateIoBlockEx(pCtx) (!CPUMIsGuestInPagedProtectedModeEx(pCtx)) - -VMMDECL(int) HWACCMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt); -VMMDECL(bool) HWACCMHasPendingIrq(PVM pVM); - -#ifndef IN_RC -VMMDECL(int) HWACCMFlushTLB(PVMCPU pVCpu); -VMMDECL(int) HWACCMFlushTLBOnAllVCpus(PVM pVM); -VMMDECL(int) HWACCMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt); -VMMDECL(int) HWACCMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys); -VMMDECL(bool) HWACCMIsNestedPagingActive(PVM pVM); -VMMDECL(PGMMODE) HWACCMGetShwPagingMode(PVM pVM); -#else -/* Nop in GC */ -# define HWACCMFlushTLB(pVCpu) do { } while (0) -# define HWACCMIsNestedPagingActive(pVM) false -# define HWACCMFlushTLBOnAllVCpus(pVM) do { } while (0) -#endif - -#ifdef IN_RING0 -/** @defgroup grp_hwaccm_r0 The VM Hardware Manager API - * @ingroup grp_hwaccm - * @{ - */ -VMMR0DECL(int) HWACCMR0Init(void); -VMMR0DECL(int) HWACCMR0Term(void); -VMMR0DECL(int) HWACCMR0InitVM(PVM pVM); -VMMR0DECL(int) HWACCMR0TermVM(PVM pVM); -VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM); -VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled); -VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled); - -VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize); -VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize); - -/** @} */ -#endif /* IN_RING0 */ - - -#ifdef IN_RING3 -/** @defgroup grp_hwaccm_r3 The VM Hardware Manager API - * @ingroup grp_hwaccm - * @{ - */ -VMMR3DECL(bool) HWACCMR3IsEventPending(PVMCPU pVCpu); -VMMR3DECL(int) HWACCMR3Init(PVM pVM); -VMMR3_INT_DECL(int) HWACCMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); -VMMR3DECL(void) HWACCMR3Relocate(PVM pVM); -VMMR3DECL(int) HWACCMR3Term(PVM pVM); -VMMR3DECL(void) HWACCMR3Reset(PVM pVM); -VMMR3DECL(void) HWACCMR3ResetCpu(PVMCPU pVCpu); -VMMR3DECL(void) HWACCMR3CheckError(PVM pVM, int iStatusCode); -VMMR3DECL(bool) HWACCMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx); -VMMR3DECL(void) HWACCMR3NotifyScheduled(PVMCPU pVCpu); -VMMR3DECL(void) HWACCMR3NotifyEmulated(PVMCPU pVCpu); -VMMR3DECL(bool) HWACCMR3IsActive(PVMCPU pVCpu); -VMMR3DECL(bool) HWACCMR3IsNestedPagingActive(PVM pVM); -VMMR3DECL(bool) HWACCMR3IsAllowed(PVM pVM); -VMMR3DECL(void) HWACCMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode); -VMMR3DECL(bool) HWACCMR3IsVPIDActive(PVM pVM); -VMMR3DECL(int) HWACCMR3InjectNMI(PVM pVM); -VMMR3DECL(int) HWACCMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx); -VMMR3DECL(VBOXSTRICTRC) HWACCMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR3DECL(int) HWACMMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); -VMMR3DECL(int) HWACMMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); -VMMR3DECL(int) HWACCMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR3DECL(bool) HWACCMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx); -VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM); - -/** @} */ -#endif /* IN_RING3 */ - -#ifdef IN_RING0 -/** @addtogroup grp_hwaccm_r0 - * @{ - */ -VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM); -VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0InvalidatePage(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0FlushTLB(PVM pVM); -VMMR0DECL(bool) HWACCMR0SuspendPending(void); - -# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) -VMMR0DECL(int) HWACCMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) HWACCMR0TestSwitcher3264(PVM pVM); -# endif - -/** @} */ -#endif /* IN_RING0 */ - - -/** @} */ -RT_C_DECLS_END - - -#endif - diff --git a/include/VBox/vmm/iem.h b/include/VBox/vmm/iem.h index 617a05a6..32168660 100644 --- a/include/VBox/vmm/iem.h +++ b/include/VBox/vmm/iem.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -28,6 +28,7 @@ #include #include +#include RT_C_DECLS_BEGIN @@ -37,6 +38,17 @@ RT_C_DECLS_BEGIN */ +/** + * Operand or addressing mode. + */ +typedef enum IEMMODE +{ + IEMMODE_16BIT = 0, + IEMMODE_32BIT, + IEMMODE_64BIT +} IEMMODE; +AssertCompileSize(IEMMODE, 4); + VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu); VMMDECL(VBOXSTRICTRC) IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten); @@ -53,7 +65,10 @@ VMM_INT_DECL(int) IEMBreakpointClear(PVM pVM, RTGCPTR GCPtrBp); /** @name Given Instruction Interpreters * @{ */ - +VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, + bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg); +VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, + bool fRepPrefix, uint8_t cbInstr); /** @} */ #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3) diff --git a/include/VBox/vmm/iom.h b/include/VBox/vmm/iom.h index a7e552c9..a69ac4cd 100644 --- a/include/VBox/vmm/iom.h +++ b/include/VBox/vmm/iom.h @@ -3,7 +3,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; @@ -57,13 +57,11 @@ RT_C_DECLS_BEGIN * more than once! * * @remark To avoid making assumptions about the layout of the - * VINF_EM_FIRST...VINF_EM_LAST range we're checking - * explicitly for each for exach the exceptions. - * However, for efficieny we ASSUME that the - * VINF_EM_LAST is smaller than most of the relevant - * status codes. We also ASSUME that the - * VINF_EM_RESCHEDULE_REM status code is the most - * frequent status code we'll enounter in this range. + * VINF_EM_FIRST...VINF_EM_LAST range we're checking explicitly for + * each exact exception. However, for efficiency we ASSUME that the + * VINF_EM_LAST is smaller than most of the relevant status codes. We + * also ASSUME that the VINF_EM_RESCHEDULE_REM status code is the + * most frequent status code we'll enounter in this range. * * @todo Will have to add VINF_EM_DBG_HYPER_BREAKPOINT if the * I/O port and MMIO breakpoints should trigger before @@ -75,7 +73,7 @@ RT_C_DECLS_BEGIN && (rc) != VINF_EM_RESCHEDULE_REM \ && (rc) >= VINF_EM_FIRST \ && (rc) != VINF_EM_RESCHEDULE_RAW \ - && (rc) != VINF_EM_RESCHEDULE_HWACC \ + && (rc) != VINF_EM_RESCHEDULE_HM \ ) \ ) @@ -116,6 +114,16 @@ RT_C_DECLS_BEGIN * simplifications of devices where reads doesn't change the device * state in any way. */ #define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING UINT32_C(0x00000040) +/** All write accesses are DWORD (32-bit) sized and aligned, attempts at other + * accesses are ignored. + * @remarks E1000, APIC */ +#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD UINT32_C(0x00000050) +/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and aligned, + * attempts at other accesses are ignored. + * @remarks Seemingly required by AHCI (although I doubt it's _really_ + * required as EM/REM doesn't do the right thing in ring-3 anyway, + * esp. not in raw-mode). */ +#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD UINT32_C(0x00000060) /** The read access mode mask. */ #define IOMMMIO_FLAGS_WRITE_MODE UINT32_C(0x00000070) @@ -132,6 +140,14 @@ RT_C_DECLS_BEGIN #define IOMMMIO_FLAGS_VALID_MASK UINT32_C(0x00000373) /** @} */ +/** + * Checks whether the write mode allows aligned QWORD accesses to be passed + * thru to the device handler. + * @param a_fFlags The MMIO handler flags. + * @remarks The current implementation makes ASSUMPTIONS about the mode values! + */ +#define IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD(a_fFlags) RT_BOOL((a_fFlags) & UINT32_C(0x00000020)) + /** * Port I/O Handler for IN operations. @@ -145,6 +161,7 @@ RT_C_DECLS_BEGIN * @param pu32 Where to store the result. This is always a 32-bit * variable regardless of what @a cb might say. * @param cb Number of bytes read. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); /** Pointer to a FNIOMIOPORTIN(). */ @@ -162,6 +179,7 @@ typedef FNIOMIOPORTIN *PFNIOMIOPORTIN; * @param pGCPtrDst Pointer to the destination buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); /** Pointer to a FNIOMIOPORTINSTRING(). */ @@ -177,6 +195,7 @@ typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING; * @param uPort Port number used for the OUT operation. * @param u32 The value to output. * @param cb The value size in bytes. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); /** Pointer to a FNIOMIOPORTOUT(). */ @@ -193,6 +212,7 @@ typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT; * @param pGCPtrSrc Pointer to the source buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); /** Pointer to a FNIOMIOPORTOUTSTRING(). */ @@ -209,6 +229,7 @@ typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING; * @param GCPhysAddr Physical address (in GC) where the read starts. * @param pv Where to store the result. * @param cb Number of bytes read. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb); /** Pointer to a FNIOMMMIOREAD(). */ @@ -224,6 +245,7 @@ typedef FNIOMMMIOREAD *PFNIOMMMIOREAD; * @param GCPhysAddr Physical address (in GC) where the read starts. * @param pv Where to fetch the result. * @param cb Number of bytes to write. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb); /** Pointer to a FNIOMMMIOWRITE(). */ @@ -240,36 +262,37 @@ typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE; * @param u32Item Byte/Word/Dword data to fill. * @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes. * @param cItems Number of iterations. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems); /** Pointer to a FNIOMMMIOFILL(). */ typedef FNIOMMMIOFILL *PFNIOMMMIOFILL; -VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); -VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); -VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); -VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); -VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault); +VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); +VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); +VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); +VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); +VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault); VMMDECL(VBOXSTRICTRC) IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb); VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags); -VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags); +VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags); VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys); -VMMDECL(bool) IOMIsLockOwner(PVM pVM); +VMMDECL(bool) IOMIsLockWriteOwner(PVM pVM); #ifdef IN_RC /** @defgroup grp_iom_rc The IOM Raw-Mode Context API * @ingroup grp_iom * @{ */ -VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); /** @} */ #endif /* IN_RC */ diff --git a/include/VBox/vmm/mm.h b/include/VBox/vmm/mm.h index 66490fce..bcb55c14 100644 --- a/include/VBox/vmm/mm.h +++ b/include/VBox/vmm/mm.h @@ -3,7 +3,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; @@ -58,6 +58,8 @@ typedef enum MMTAG MM_TAG_CSAM_PATCH, MM_TAG_CPUM_CTX, + MM_TAG_CPUM_CPUID, + MM_TAG_CPUM_MSRS, MM_TAG_DBGF, MM_TAG_DBGF_AS, @@ -130,7 +132,7 @@ typedef enum MMTAG MM_TAG_VMM, - MM_TAG_HWACCM, + MM_TAG_HM, MM_TAG_32BIT_HACK = 0x7fffffff } MMTAG; @@ -205,6 +207,7 @@ DECLINLINE(RTRCPTR) MMHyperCCToRC(PVM pVM, void *pv) VMMDECL(int) MMHyperAlloc(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv); +VMMDECL(int) MMHyperDupMem(PVM pVM, const void *pvSrc, size_t cb, unsigned uAlignment, MMTAG enmTag, void **ppv); VMMDECL(int) MMHyperFree(PVM pVM, void *pv); VMMDECL(void) MMHyperHeapCheck(PVM pVM); VMMDECL(int) MMR3LockCall(PVM pVM); diff --git a/include/VBox/vmm/patm.h b/include/VBox/vmm/patm.h index 70b7fa55..6f9adca0 100644 --- a/include/VBox/vmm/patm.h +++ b/include/VBox/vmm/patm.h @@ -3,7 +3,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; @@ -29,6 +29,7 @@ #include #include +#if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING) RT_C_DECLS_BEGIN @@ -41,18 +42,18 @@ RT_C_DECLS_BEGIN * Flags for specifying the type of patch to install with PATMR3InstallPatch * @{ */ -#define PATMFL_CODE32 RT_BIT_64(0) -#define PATMFL_INTHANDLER RT_BIT_64(1) -#define PATMFL_SYSENTER RT_BIT_64(2) -#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3) -#define PATMFL_USER_MODE RT_BIT_64(4) -#define PATMFL_IDTHANDLER RT_BIT_64(5) -#define PATMFL_TRAPHANDLER RT_BIT_64(6) -#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7) -#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8) +#define PATMFL_CODE32 RT_BIT_64(0) +#define PATMFL_INTHANDLER RT_BIT_64(1) +#define PATMFL_SYSENTER RT_BIT_64(2) +#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3) +#define PATMFL_USER_MODE RT_BIT_64(4) +#define PATMFL_IDTHANDLER RT_BIT_64(5) +#define PATMFL_TRAPHANDLER RT_BIT_64(6) +#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7) +#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8) #define PATMFL_TRAPHANDLER_WITH_ERRORCODE RT_BIT_64(9) #define PATMFL_INTHANDLER_WITH_ERRORCODE (PATMFL_TRAPHANDLER_WITH_ERRORCODE) -#define PATMFL_MMIO_ACCESS RT_BIT_64(10) +#define PATMFL_MMIO_ACCESS RT_BIT_64(10) /* no more room -> change PATMInternal.h if more is needed!! */ /* @@ -70,32 +71,32 @@ RT_C_DECLS_BEGIN typedef struct PATMGCSTATE { - /* Virtual Flags register (IF + more later on) */ + /** Virtual Flags register (IF + more later on) */ uint32_t uVMFlags; - /* Pending PATM actions (internal use only) */ + /** Pending PATM actions (internal use only) */ uint32_t uPendingAction; - /* Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */ + /** Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */ uint32_t uPatchCalls; - /* Scratchpad dword */ + /** Scratchpad dword */ uint32_t uScratch; - /* Debugging info */ + /** Debugging info */ uint32_t uIretEFlags, uIretCS, uIretEIP; - /* PATM stack pointer */ + /** PATM stack pointer */ uint32_t Psp; - /* PATM interrupt flag */ + /** PATM interrupt flag */ uint32_t fPIF; - /* PATM inhibit irq address (used by sti) */ + /** PATM inhibit irq address (used by sti) */ RTRCPTR GCPtrInhibitInterrupts; - /* Scratch room for call patch */ + /** Scratch room for call patch */ RTRCPTR GCCallPatchTargetAddr; RTRCPTR GCCallReturnAddr; - /* Temporary storage for guest registers. */ + /** Temporary storage for guest registers. */ struct { uint32_t uEAX; @@ -108,11 +109,11 @@ typedef struct PATMGCSTATE typedef struct PATMTRAPREC { - /* pointer to original guest code instruction (for emulation) */ + /** pointer to original guest code instruction (for emulation) */ RTRCPTR pNewEIP; - /* pointer to the next guest code instruction */ + /** pointer to the next guest code instruction */ RTRCPTR pNextInstr; - /* pointer to the corresponding next instruction in the patch block */ + /** pointer to the corresponding next instruction in the patch block */ RTRCPTR pNextPatchInstr; } PATMTRAPREC, *PPATMTRAPREC; @@ -122,198 +123,50 @@ typedef struct PATMTRAPREC */ typedef enum { - PATMTRANS_FAILED, - PATMTRANS_SAFE, /* Safe translation */ - PATMTRANS_PATCHSTART, /* Instruction starts a patch block */ - PATMTRANS_OVERWRITTEN, /* Instruction overwritten by patchjump */ - PATMTRANS_INHIBITIRQ /* Instruction must be executed due to instruction fusing */ + PATMTRANS_FAILED, + PATMTRANS_SAFE, /**< Safe translation */ + PATMTRANS_PATCHSTART, /**< Instruction starts a patch block */ + PATMTRANS_OVERWRITTEN, /**< Instruction overwritten by patchjump */ + PATMTRANS_INHIBITIRQ /**< Instruction must be executed due to instruction fusing */ } PATMTRANSSTATE; -/** - * Load virtualized flags. - * - * This function is called from CPUMRawEnter(). It doesn't have to update the - * IF and IOPL eflags bits, the caller will enforce those to set and 0 respectively. - * - * @param pVM VM handle. - * @param pCtxCore The cpu context core. - * @see pg_raw - */ -VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore); - -/** - * Restores virtualized flags. - * - * This function is called from CPUMRawLeave(). It will update the eflags register. - * - * @param pVM VM handle. - * @param pCtxCore The cpu context core. - * @param rawRC Raw mode return code - * @see @ref pg_raw - */ -VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC); - -/** - * Get the EFLAGS. - * This is a worker for CPUMRawGetEFlags(). - * - * @returns The eflags. - * @param pVM The VM handle. - * @param pCtxCore The context core. - */ -VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore); - -/** - * Updates the EFLAGS. - * This is a worker for CPUMRawSetEFlags(). - * - * @param pVM The VM handle. - * @param pCtxCore The context core. - * @param efl The new EFLAGS value. - */ -VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl); - -/** - * Returns the guest context pointer of the GC context structure - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM); - -/** - * Checks whether the GC address is part of our patch region - * - * @returns true -> yes, false -> no - * @param pVM The VM to operate on. - * @param pAddr Guest context address - */ -VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr); - -/** - * Check if we must use raw mode (patch code being executed or marked safe for IF=0) - * - * @param pVM VM handle. - * @param pAddrGC Guest context address - */ -VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC); /** * Query PATM state (enabled/disabled) * * @returns 0 - disabled, 1 - enabled * @param pVM The VM to operate on. + * @internal */ -#define PATMIsEnabled(pVM) (pVM->fPATMEnabled) +#define PATMIsEnabled(a_pVM) ((a_pVM)->fPATMEnabled) -/** - * Set parameters for pending MMIO patch operation - * - * @returns VBox status code. - * @param pDevIns Device instance. - * @param GCPhys MMIO physical address - * @param pCachedData GC pointer to cached data - */ -VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData); - - -/** - * Adds branch pair to the lookup cache of the particular branch instruction - * - * @returns VBox status - * @param pVM The VM to operate on. - * @param pJumpTableGC Pointer to branch instruction lookup cache - * @param pBranchTarget Original branch target - * @param pRelBranchPatch Relative duplicated function address - */ -VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch); - - -/** - * Checks if the int 3 was caused by a patched instruction - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pCtxCore The relevant core context. - */ -VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame); - -/** - * Checks if the int 3 was caused by a patched instruction - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pInstrGC Instruction pointer - * @param pOpcode Original instruction opcode (out, optional) - * @param pSize Original instruction size (out, optional) - */ -VMMDECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize); - - -/** - * Checks if the interrupt flag is enabled or not. - * - * @returns true if it's enabled. - * @returns false if it's disabled. - * - * @param pVM The VM handle. - */ -VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM); +VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr); +VMM_INT_DECL(int) PATMReadPatchCode(PVM pVM, RTGCPTR GCPtrPatchCode, void *pvDst, size_t cbToRead, size_t *pcbRead); -/** - * Checks if the interrupt flag is enabled or not. - * - * @returns true if it's enabled. - * @returns false if it's disabled. - * - * @param pVM The VM handle. - * @param pCtxCore CPU context - */ -VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore); +VMM_INT_DECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore); +VMM_INT_DECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC); +VMM_INT_DECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore); +VMM_INT_DECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl); +VMM_INT_DECL(RCPTRTYPE(PPATMGCSTATE)) PATMGetGCState(PVM pVM); +VMM_INT_DECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC); +VMM_INT_DECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData); +VMM_INT_DECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize); +VMM_INT_DECL(bool) PATMAreInterruptsEnabled(PVM pVM); +VMM_INT_DECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore); #ifdef PATM_EMULATE_SYSENTER -/** - * Emulate sysenter, sysexit and syscall instructions - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pCtxCore The relevant core context. - * @param pCpu Disassembly context - */ -VMMDECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMM_INT_DECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); #endif #ifdef IN_RC -/** @defgroup grp_patm_gc The Patch Manager API +/** @defgroup grp_patm_rc The Patch Manager RC API * @ingroup grp_patm * @{ */ -/** - * Checks if the write is located on a page with was patched before. - * (if so, then we are not allowed to turn on r/w) - * - * @returns VBox status - * @param pVM The VM to operate on. - * @param pRegFrame CPU context - * @param GCPtr GC pointer to write address - * @param cbWrite Nr of bytes to write - * - */ -VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite); - -/** - * Checks if the illegal instruction was caused by a patched instruction - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pCtxCore The relevant core context. - */ -VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); +VMMRC_INT_DECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame); +VMMRC_INT_DECL(int) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite); +VMMRC_INT_DECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); /** @} */ @@ -325,341 +178,41 @@ VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); * @{ */ -/** - * Query PATM state (enabled/disabled) - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3IsEnabled(PVM pVM); - -/** - * Initializes the PATM. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3Init(PVM pVM); - -/** - * Finalizes HMA page attributes. - * - * @returns VBox status code. - * @param pVM The VM handle. - */ -VMMR3DECL(int) PATMR3InitFinalize(PVM pVM); - -/** - * Applies relocations to data and code managed by this - * component. This function will be called at init and - * whenever the VMM need to relocate it self inside the GC. - * - * The PATM will update the addresses used by the switcher. - * - * @param pVM The VM. - */ -VMMR3DECL(void) PATMR3Relocate(PVM pVM); - -/** - * Terminates the PATM. - * - * Termination means cleaning up and freeing all resources, - * the VM it self is at this point powered off or suspended. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3Term(PVM pVM); - -/** - * PATM reset callback. - * - * @returns VBox status code. - * @param pVM The VM which is reset. - */ -VMMR3DECL(int) PATMR3Reset(PVM pVM); - -/** - * Returns the host context pointer and size of the patch memory block - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pcb Size of the patch memory block - */ -VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb); - -/** - * Returns the guest context pointer and size of the patch memory block - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pcb Size of the patch memory block - */ -VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb); - -/** - * Checks whether the GC address is inside a generated patch jump - * - * @returns true -> yes, false -> no - * @param pVM The VM to operate on. - * @param pAddr Guest context address - * @param pPatchAddr Guest context patch address (if true) - */ -VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr); - - -/** - * Returns the GC pointer of the patch for the specified GC address - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pAddrGC Guest context address - */ -VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC); - -/** - * Checks whether the HC address is part of our patch region - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pAddrGC Guest context address - */ -VMMR3DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, R3PTRTYPE(uint8_t *) pAddrHC); - -/** - * Convert a GC patch block pointer to a HC patch pointer - * - * @returns HC pointer or NULL if it's not a GC patch pointer - * @param pVM The VM to operate on. - * @param pAddrGC GC pointer - */ -VMMR3DECL(R3PTRTYPE(void *)) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC); - - -/** - * Returns the host context pointer and size of the GC context structure - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM); - -/** - * Handle trap inside patch code - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pCtx CPU context - * @param pEip GC pointer of trapping instruction - * @param pNewEip GC pointer to new instruction - */ -VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip); - -/** - * Handle page-fault in monitored page - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3HandleMonitoredPage(PVM pVM); - -/** - * Notifies PATM about a (potential) write to code that has been patched. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param GCPtr GC pointer to write address - * @param cbWrite Nr of bytes to write - * - */ -VMMR3DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite); - -/** - * Notify PATM of a page flush - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param addr GC address of the page to flush - */ -VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr); - -/** - * Allows or disallow patching of privileged instructions executed by the guest OS - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param fAllowPatching Allow/disallow patching - */ -VMMR3DECL(int) PATMR3AllowPatching(PVM pVM, uint32_t fAllowPatching); - -/** - * Patch privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction (0:32 flat address) - * @param flags Patch flags - * - * @note returns failure if patching is not allowed or possible - */ -VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags); - -/** - * Gives hint to PATM about supervisor guest instructions - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * @param flags Patch flags - */ -VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags); - -/** - * Patch branch target function for call/jump at specified location. - * (in responds to a VINF_PATM_DUPLICATE_FUNCTION GC exit reason) - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pCtx Guest context - * - */ -VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx); - -/** - * Query the corresponding GC instruction pointer from a pointer inside the patch block itself - * - * @returns original GC instruction pointer or 0 if not found - * @param pVM The VM to operate on. - * @param pPatchGC GC address in patch block - * @param pEnmState State of the translated address (out) - * - */ -VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState); - -/** - * Converts Guest code GC ptr to Patch code GC ptr (if found) - * - * @returns corresponding GC pointer in patch block - * @param pVM The VM to operate on. - * @param pInstrGC Guest context pointer to privileged instruction - * - */ -VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC); - -/** - * Query the opcode of the original code that was overwritten by the 5 bytes patch jump - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstrGC GC address of instr - * @param pByte opcode byte pointer (OUT) - * @returns VBOX error code - * - */ -VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte); -VMMR3DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead); - -/** - * Disable patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Enable patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Remove patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Detects it the specified address falls within a 5 byte jump generated for an active patch. - * If so, this patch is permanently disabled. - * - * @param pVM The VM to operate on. - * @param pInstrGC Guest context pointer to instruction - * @param pConflictGC Guest context pointer to check - */ -VMMR3DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC); - - -/** - * Checks if the instructions at the specified address has been patched already. - * - * @returns boolean, patched or not - * @param pVM The VM to operate on. - * @param pInstrGC Guest context pointer to instruction - */ -VMMR3DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Install Linux 2.6 spinlock patch - * - * @returns VBox status code. - * @param pVM The VM to operate on - * @param pCallAcquireSpinlockGC GC pointer of call instruction - * @param cbAcquireSpinlockCall Instruction size - * - */ -VMMR3DECL(int) PATMInstallSpinlockPatch(PVM pVM, RTRCPTR pCallAcquireSpinlockGC, uint32_t cbAcquireSpinlockCall); - - -/** - * Check if supplied call target is the Linux 2.6 spinlock acquire function - * - * @returns boolean - * @param pVM The VM to operate on - * @param pCallAcquireSpinlockGC Call target GC address - * - */ -VMMR3DECL(bool) PATMIsSpinlockAcquire(PVM pVM, RTRCPTR pCallTargetGC); - -/** - * Check if supplied call target is the Linux 2.6 spinlock release function - * - * @returns boolean - * @param pVM The VM to operate on - * @param pCallTargetGC Call target GC address - * - */ -VMMR3DECL(bool) PATMIsSpinlockRelease(PVM pVM, RTRCPTR pCallTargetGC); - -/** - * Check if supplied call target is the Linux 2.6 spinlock release function (patched equivalent) - * - * @returns boolean - * @param pVM The VM to operate on - * @param pCallTargetGC Call target GC address - * - */ -VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC); +VMMR3DECL(int) PATMR3AllowPatching(PUVM pUVM, bool fAllowPatching); +VMMR3DECL(bool) PATMR3IsEnabled(PUVM pUVM); + +VMMR3_INT_DECL(int) PATMR3Init(PVM pVM); +VMMR3_INT_DECL(int) PATMR3InitFinalize(PVM pVM); +VMMR3_INT_DECL(void) PATMR3Relocate(PVM pVM); +VMMR3_INT_DECL(int) PATMR3Term(PVM pVM); +VMMR3_INT_DECL(int) PATMR3Reset(PVM pVM); + +VMMR3_INT_DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb); +VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb); +VMMR3_INT_DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr); +VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC); +VMMR3_INT_DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, void *pAddrHC); +VMMR3_INT_DECL(void *) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC); +VMMR3_INT_DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM); +VMMR3_INT_DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip); +VMMR3_INT_DECL(int) PATMR3HandleMonitoredPage(PVM pVM); +VMMR3_INT_DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite); +VMMR3_INT_DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr); +VMMR3_INT_DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags); +VMMR3_INT_DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags); +VMMR3_INT_DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState); +VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte); +VMMR3_INT_DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead); +VMMR3_INT_DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC); +VMMR3_INT_DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC); + +VMMR3_INT_DECL(void) PATMR3DbgPopulateAddrSpace(PVM pVM, RTDBGAS hDbgAs); +VMMR3_INT_DECL(void) PATMR3DbgAnnotatePatchedInstruction(PVM pVM, RTRCPTR RCPtr, uint8_t cbInstr, + char *pszBuf, size_t cbBuf); /** @} */ #endif @@ -668,5 +221,6 @@ VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC); /** @} */ RT_C_DECLS_END +#endif /* VBOX_WITH_RAW_MODE */ #endif diff --git a/include/VBox/vmm/pdm.h b/include/VBox/vmm/pdm.h index ff95ea82..527d3d14 100644 --- a/include/VBox/vmm/pdm.h +++ b/include/VBox/vmm/pdm.h @@ -3,7 +3,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; @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/include/VBox/vmm/pdmapi.h b/include/VBox/vmm/pdmapi.h index 1fb8aef6..321865a1 100644 --- a/include/VBox/vmm/pdmapi.h +++ b/include/VBox/vmm/pdmapi.h @@ -7,7 +7,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; @@ -40,20 +40,21 @@ RT_C_DECLS_BEGIN * @{ */ -VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt); -VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); -VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); -VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc); -VMMDECL(bool) PDMHasIoApic(PVM pVM); -VMMDECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending); -VMMDECL(int) PDMApicSetBase(PVM pVM, uint64_t u64Base); -VMMDECL(int) PDMApicGetBase(PVM pVM, uint64_t *pu64Base); -VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR); -VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending); -VMMDECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value); -VMMDECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value); -VMMDECL(int) PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys); -VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM); +VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt); +VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); +VMM_INT_DECL(bool) PDMHasIoApic(PVM pVM); +VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); +VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc); +VMM_INT_DECL(bool) PDMHasApic(PVM pVM); +VMM_INT_DECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending); +VMMDECL(int) PDMApicSetBase(PVMCPU pVCpu, uint64_t u64Base); +VMMDECL(int) PDMApicGetBase(PVMCPU pVCpu, uint64_t *pu64Base); +VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR); +VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIrq); +VMM_INT_DECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value); +VMM_INT_DECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value); +VMM_INT_DECL(int) PDMVmmDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys); +VMM_INT_DECL(bool) PDMVmmDevHeapIsEnabled(PVM pVM); /** @defgroup grp_pdm_r3 The PDM Host Context Ring-3 API @@ -61,18 +62,36 @@ VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM); * @{ */ -VMMR3DECL(int) PDMR3InitUVM(PUVM pUVM); -VMMR3DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM); -VMMR3DECL(int) PDMR3Init(PVM pVM); -VMMR3DECL(void) PDMR3PowerOn(PVM pVM); -VMMR3DECL(void) PDMR3ResetCpu(PVMCPU pVCpu); -VMMR3DECL(void) PDMR3Reset(PVM pVM); -VMMR3DECL(void) PDMR3Suspend(PVM pVM); -VMMR3DECL(void) PDMR3Resume(PVM pVM); -VMMR3DECL(void) PDMR3PowerOff(PVM pVM); -VMMR3DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(int) PDMR3Term(PVM pVM); -VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM); +VMMR3_INT_DECL(int) PDMR3InitUVM(PUVM pUVM); +VMMR3_INT_DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM); +VMMR3_INT_DECL(int) PDMR3Init(PVM pVM); +VMMR3DECL(void) PDMR3PowerOn(PVM pVM); +VMMR3_INT_DECL(void) PDMR3ResetCpu(PVMCPU pVCpu); +VMMR3_INT_DECL(void) PDMR3Reset(PVM pVM); +VMMR3_INT_DECL(void) PDMR3MemSetup(PVM pVM, bool fAtReset); +VMMR3_INT_DECL(void) PDMR3Suspend(PVM pVM); +VMMR3_INT_DECL(void) PDMR3Resume(PVM pVM); +VMMR3DECL(void) PDMR3PowerOff(PVM pVM); +VMMR3_INT_DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) PDMR3Term(PVM pVM); +VMMR3_INT_DECL(void) PDMR3TermUVM(PUVM pUVM); + +/** PDM loader context indicator. */ +typedef enum PDMLDRCTX +{ + /** Invalid zero value. */ + PDMLDRCTX_INVALID = 0, + /** Ring-0 context. */ + PDMLDRCTX_RING_0, + /** Ring-3 context. */ + PDMLDRCTX_RING_3, + /** Raw-mode context. */ + PDMLDRCTX_RAW_MODE, + /** End of valid context values. */ + PDMLDRCTX_END, + /** 32-bit type hack. */ + PDMLDRCTX_32BIT_HACK = 0x7fffffff +} PDMLDRCTX; /** * Module enumeration callback function. @@ -85,54 +104,57 @@ VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM); * @param pszName Module name. (short and unique) * @param ImageBase Address where to executable image is loaded. * @param cbImage Size of the executable image. - * @param fRC Set if raw-mode context, clear if host context. + * @param enmCtx The context the module is loaded into. * @param pvArg User argument. */ typedef DECLCALLBACK(int) FNPDMR3ENUM(PVM pVM, const char *pszFilename, const char *pszName, - RTUINTPTR ImageBase, size_t cbImage, bool fRC, void *pvArg); + RTUINTPTR ImageBase, size_t cbImage, PDMLDRCTX enmCtx, void *pvArg); /** Pointer to a FNPDMR3ENUM() function. */ typedef FNPDMR3ENUM *PFNPDMR3ENUM; -VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg); -VMMR3DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta); -VMMR3DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue); -VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue); -VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue); -VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName); -VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue); -VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTRCPTR pRCPtrValue); -VMMR3DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC, - char *pszModName, size_t cchModName, PRTRCPTR pMod, - char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1, - char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2); -VMMR3DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC, - char *pszModName, size_t cchModName, PRTR0PTR pMod, - char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1, - char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2); -VMMR3DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM, - void *pvInterface, size_t cbInterface, - const char *pszModule, const char *pszSearchPath, - const char *pszSymPrefix, const char *pszSymList, - bool fRing0OrRC); - -VMMR3DECL(int) PDMR3QueryDevice(PVM pVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3QueryDeviceLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3QueryLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3QueryDriverOnLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, const char *pszDriver, - PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, PPDMIBASE *ppBase); -VMMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags); +VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg); +VMMR3_INT_DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue); +VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue); +VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue); +VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName); +VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue); +VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, + PRTRCPTR pRCPtrValue); +VMMR3_INT_DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC, + char *pszModName, size_t cchModName, PRTRCPTR pMod, + char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1, + char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2); +VMMR3_INT_DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC, + char *pszModName, size_t cchModName, PRTR0PTR pMod, + char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1, + char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2); +VMMR3_INT_DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM, void *pvInterface, size_t cbInterface, + const char *pszModule, const char *pszSearchPath, + const char *pszSymPrefix, const char *pszSymList, + bool fRing0OrRC); + +VMMR3DECL(int) PDMR3QueryDevice(PUVM pUVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3QueryDeviceLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3QueryLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3QueryDriverOnLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, + const char *pszDriver, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3DeviceAttach(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, + PPDMIBASE *ppBase); +VMMR3DECL(int) PDMR3DeviceDetach(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags); VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns); -VMMR3DECL(int) PDMR3DriverAttach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3DriverDetach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, - const char *pszDriver, unsigned iOccurance, uint32_t fFlags); -VMMR3DECL(int) PDMR3DriverReattach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, - const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg, PPPDMIBASE ppBase); -VMMR3DECL(void) PDMR3DmaRun(PVM pVM); -VMMR3DECL(int) PDMR3LockCall(PVM pVM); -VMMR3DECL(int) PDMR3RegisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize); -VMMR3DECL(int) PDMR3VMMDevHeapAlloc(PVM pVM, unsigned cbSize, RTR3PTR *ppv); -VMMR3DECL(int) PDMR3VMMDevHeapFree(PVM pVM, RTR3PTR pv); -VMMR3DECL(int) PDMR3UnregisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys); +VMMR3DECL(int) PDMR3DriverAttach(PUVM pUVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, + PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3DriverDetach(PUVM pUVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, + const char *pszDriver, unsigned iOccurance, uint32_t fFlags); +VMMR3DECL(int) PDMR3DriverReattach(PUVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, + const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg, + PPPDMIBASE ppBase); +VMMR3DECL(void) PDMR3DmaRun(PVM pVM); +VMMR3_INT_DECL(int) PDMR3LockCall(PVM pVM); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapRegister(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapUnregister(PVM pVM, RTGCPHYS GCPhys); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapAlloc(PVM pVM, size_t cbSize, RTR3PTR *ppv); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapFree(PVM pVM, RTR3PTR pv); VMMR3_INT_DECL(int) PDMR3TracingConfig(PVM pVM, const char *pszName, size_t cchName, bool fEnable, bool fApply); VMMR3_INT_DECL(bool) PDMR3TracingAreAll(PVM pVM, bool fEnabled); VMMR3_INT_DECL(int) PDMR3TracingQueryConfig(PVM pVM, char *pszConfig, size_t cbConfig); diff --git a/include/VBox/vmm/pdmasynccompletion.h b/include/VBox/vmm/pdmasynccompletion.h index 1d1af265..74285945 100644 --- a/include/VBox/vmm/pdmasynccompletion.h +++ b/include/VBox/vmm/pdmasynccompletion.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-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; @@ -104,122 +104,8 @@ typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pv /** Pointer to a FNPDMASYNCCOMPLETEINT(). */ typedef FNPDMASYNCCOMPLETEINT *PFNPDMASYNCCOMPLETEINT; - -/** - * Creates an async completion template for a device instance. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pDevIns The device instance. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pszDesc Description. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc); - -/** - * Creates an async completion template for a driver instance. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pDrvIns The driver instance. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pvTemplateUser Template user argument. - * @param pszDesc Description. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc); - -/** - * Creates an async completion template for a USB device instance. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pUsbIns The USB device instance. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pszDesc Description. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc); - -/** - * Creates an async completion template for internally by the VMM. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pvUser2 The 2nd user argument for the callback. - * @param pszDesc Description. - */ VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateInternal(PVM pVM, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEINT pfnCompleted, void *pvUser2, const char *pszDesc); - -/** - * Destroys the specified async completion template. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if the template is still in use. - * - * @param pTemplate The template in question. - */ VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroy(PPDMASYNCCOMPLETIONTEMPLATE pTemplate); - -/** - * Destroys all the specified async completion templates for the given device instance. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use. - * - * @param pVM Pointer to the shared VM structure. - * @param pDevIns The device instance. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns); - -/** - * Destroys all the specified async completion templates for the given driver instance. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use. - * - * @param pVM Pointer to the shared VM structure. - * @param pDrvIns The driver instance. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns); - -/** - * Destroys all the specified async completion templates for the given USB device instance. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use. - * - * @param pVM Pointer to the shared VM structure. - * @param pUsbIns The USB device instance. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns); - - -/** - * Opens a file as an async completion endpoint. - * - * @returns VBox status code. - * @param ppEndpoint Where to store the opaque endpoint handle on success. - * @param pszFilename Path to the file which is to be opened. (UTF-8) - * @param fFlags Open flags, see grp_pdmacep_file_flags. - * @param pTemplate Handle to the completion callback template to use - * for this end point. - */ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT ppEndpoint, const char *pszFilename, uint32_t fFlags, PPDMASYNCCOMPLETIONTEMPLATE pTemplate); @@ -238,127 +124,21 @@ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT #define PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED RT_BIT_32(3) /** @} */ -/** - * Closes a endpoint waiting for any pending tasks to finish. - * - * @returns nothing. - * @param pEndpoint Handle of the endpoint. - */ VMMR3DECL(void) PDMR3AsyncCompletionEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint); - -/** - * Creates a read task on the given endpoint. - * - * @returns VBox status code. - * @param pEndpoint The file endpoint to read from. - * @param off Where to start reading from. - * @param paSegments Scatter gather list to store the data in. - * @param cSegments Number of segments in the list. - * @param cbRead The overall number of bytes to read. - * @param pvUser Opaque user data returned in the completion callback - * upon completion of the task. - * @param ppTask Where to store the task handle on success. - */ VMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off, PCRTSGSEG paSegments, unsigned cSegments, size_t cbRead, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask); - -/** - * Creates a write task on the given endpoint. - * - * @returns VBox status code. - * @param pEndpoint The file endpoint to write to. - * @param off Where to start writing at. - * @param paSegments Scatter gather list of the data to write. - * @param cSegments Number of segments in the list. - * @param cbWrite The overall number of bytes to write. - * @param pvUser Opaque user data returned in the completion callback - * upon completion of the task. - * @param ppTask Where to store the task handle on success. - */ VMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off, PCRTSGSEG paSegments, unsigned cSegments, size_t cbWrite, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask); - -/** - * Creates a flush task on the given endpoint. - * - * Every read and write task initiated before the flush task is - * finished upon completion of this task. - * - * @returns VBox status code. - * @param pEndpoint The file endpoint to flush. - * @param pvUser Opaque user data returned in the completion callback - * upon completion of the task. - * @param ppTask Where to store the task handle on success. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - void *pvUser, - PPPDMASYNCCOMPLETIONTASK ppTask); - -/** - * Queries the size of an endpoint. - * Not that some endpoints may not support this and will return an error - * (sockets for example). - * - * @returns VBox status code. - * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation. - * @param pEndpoint The file endpoint. - * @param pcbSize Where to store the size of the endpoint. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - uint64_t *pcbSize); - -/** - * Sets the size of an endpoint. - * Not that some endpoints may not support this and will return an error - * (sockets for example). - * - * @returns VBox status code. - * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation. - * @param pEndpoint The file endpoint. - * @param cbSize The size to set. - * - * @note PDMR3AsyncCompletionEpFlush should be called before this operation is executed. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - uint64_t cbSize); - -/** - * Assigns or removes a bandwidth control manager to/from the endpoint. - * - * @returns VBox status code. - * @param pEndpoint The endpoint. - * @param pcszBwMgr The identifer of the new bandwidth manager to assign - * or NULL to remove the current one. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - const char *pcszBwMgr); - -/** - * Cancels an async completion task. - * - * If you want to use this method, you have to take great create to make sure - * you will never attempt cancel a task which has been completed. Since there is - * no reference counting or anything on the task it self, you have to serialize - * the cancelation and completion paths such that the aren't racing one another. - * - * @returns VBox status code - * @param pTask The Task to cancel. - */ +VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask); +VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t *pcbSize); +VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cbSize); +VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, const char *pszBwMgr); VMMR3DECL(int) PDMR3AsyncCompletionTaskCancel(PPDMASYNCCOMPLETIONTASK pTask); - -/** - * Changes the limit of a bandwidth manager for file endpoints to the given value. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pcszBwMgr The identifer of the bandwidth manager to change. - * @param cbMaxNew The new maximum for the bandwidth manager in bytes/sec. - */ -VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PVM pVM, const char *pcszBwMgr, uint32_t cbMaxNew); +VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PUVM pUVM, const char *pszBwMgr, uint32_t cbMaxNew); /** @} */ diff --git a/include/VBox/vmm/pdmblkcache.h b/include/VBox/vmm/pdmblkcache.h index fc92bc4f..14d85f67 100644 --- a/include/VBox/vmm/pdmblkcache.h +++ b/include/VBox/vmm/pdmblkcache.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 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/include/VBox/vmm/pdmcardreaderinfs.h b/include/VBox/vmm/pdmcardreaderinfs.h index e1ad5a2d..7cb3ca75 100644 --- a/include/VBox/vmm/pdmcardreaderinfs.h +++ b/include/VBox/vmm/pdmcardreaderinfs.h @@ -1,5 +1,4 @@ /* $Id: pdmcardreaderinfs.h $ */ - /** @file * cardreaderinfs - interface between Usb Card Reader device and its driver. */ @@ -26,11 +25,10 @@ */ #ifndef ___VBox_vmm_pdmcardreaderinfs_h -# define ___VBox_vmm_pdmcardreaderinfs_h +#define ___VBox_vmm_pdmcardreaderinfs_h #include -#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817" typedef struct PDMICARDREADER_IO_REQUEST { @@ -49,41 +47,41 @@ typedef struct PDMICARDREADER_READERSTATE } PDMICARDREADER_READERSTATE; +#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817" typedef struct PDMICARDREADERDOWN PDMICARDREADERDOWN; typedef PDMICARDREADERDOWN *PPDMICARDREADERDOWN; struct PDMICARDREADERDOWN { - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEstablishContext,(PPDMICARDREADERDOWN pInterface)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName, - uint32_t u32ShareMode, uint32_t u32PreferredProtocols)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32Disposition)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t cchReaderName, uint32_t cbAtrLen)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32Timeout, PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32Disposition)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser, - const PDMICARDREADER_IO_REQUEST *pioSendRequest, - const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer)); + DECLR3CALLBACKMEMBER(int, pfnEstablishContext,(PPDMICARDREADERDOWN pInterface)); + DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName, + uint32_t u32ShareMode, uint32_t u32PreferredProtocols)); + DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Disposition)); + DECLR3CALLBACKMEMBER(int, pfnStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t cchReaderName, uint32_t cbAtrLen)); + DECLR3CALLBACKMEMBER(int, pfnReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser)); + DECLR3CALLBACKMEMBER(int, pfnGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Timeout, + PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); + DECLR3CALLBACKMEMBER(int, pfnBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser)); + DECLR3CALLBACKMEMBER(int, pfnEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Disposition)); + DECLR3CALLBACKMEMBER(int, pfnTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser, + const PDMICARDREADER_IO_REQUEST *pioSendRequest, + const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer)); /** * Up level provides pvInBuffer of cbInBuffer bytes to call SCardControl, also it specify bytes it expects to receive - * @note: device/driver implementation should copy buffers before execution in async mode, and both layers shouldn't - * expect permanent storage for the buffer. + * @note Device/driver implementation should copy buffers before execution in + * async mode, and both layers shouldn't expect permanent storage for the + * buffer. */ - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownControl,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32ControlCode, const void *pvInBuffer, uint32_t cbInBuffer, uint32_t cbOutBuffer)); + DECLR3CALLBACKMEMBER(int, pfnControl,(PPDMICARDREADERDOWN pInterface, void *pvUser, + uint32_t u32ControlCode, const void *pvInBuffer, + uint32_t cbInBuffer, uint32_t cbOutBuffer)); /** * This function ask driver to provide attribute (dwAttribId) and provide limit (cbAttrib) of buffer size for attribute value, * Callback UpGetAttrib returns buffer containing the value and altered size of the buffer. */ - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32AttribId, uint32_t cbAttrib)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib)); + DECLR3CALLBACKMEMBER(int, pfnGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, + uint32_t u32AttribId, uint32_t cbAttrib)); + DECLR3CALLBACKMEMBER(int, pfnSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, + uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib)); }; #define PDMICARDREADERUP_IID "c0d7498e-0635-48ca-aab1-b11b6a55cf7d" @@ -91,26 +89,27 @@ typedef struct PDMICARDREADERUP PDMICARDREADERUP; typedef PDMICARDREADERUP *PPDMICARDREADERUP; struct PDMICARDREADERUP { - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState, - uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32ActiveProtocol)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState, + uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr)); + DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + uint32_t u32ActiveProtocol)); + DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); + DECLR3CALLBACKMEMBER(int, pfnBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); /* Note: pioRecvPci stack variable */ - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - const PDMICARDREADER_IO_REQUEST *pioRecvPci, uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32AttribId)); + DECLR3CALLBACKMEMBER(int, pfnTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + const PDMICARDREADER_IO_REQUEST *pioRecvPci, + uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer)); + DECLR3CALLBACKMEMBER(int, pfnControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer)); + DECLR3CALLBACKMEMBER(int, pfnGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib)); + DECLR3CALLBACKMEMBER(int, pfnSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, uint32_t u32AttribId)); }; #endif + diff --git a/include/VBox/vmm/pdmcommon.h b/include/VBox/vmm/pdmcommon.h index c4e1be26..d62210a0 100644 --- a/include/VBox/vmm/pdmcommon.h +++ b/include/VBox/vmm/pdmcommon.h @@ -3,7 +3,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; @@ -109,7 +109,7 @@ typedef FNPDMUSBASYNCNOTIFY *PFNPDMUSBASYNCNOTIFY; * @returns true if done, false if more work to be done. * * @param pDevIns The device instance. - * + * @remarks The caller will enter the device critical section. * @thread EMT(0) */ typedef DECLCALLBACK(bool) FNPDMDEVASYNCNOTIFY(PPDMDEVINS pDevIns); diff --git a/include/VBox/vmm/pdmcritsect.h b/include/VBox/vmm/pdmcritsect.h index 02d7924d..0895b52b 100644 --- a/include/VBox/vmm/pdmcritsect.h +++ b/include/VBox/vmm/pdmcritsect.h @@ -3,7 +3,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; @@ -51,26 +51,31 @@ typedef union PDMCRITSECT #endif } PDMCRITSECT; +VMMR3_INT_DECL(int) PDMR3CritSectBothTerm(PVM pVM); +VMMR3_INT_DECL(void) PDMR3CritSectLeaveAll(PVM pVM); +VMM_INT_DECL(void) PDMCritSectBothFF(PVMCPU pVCpu); + + +VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames); + VMMR3DECL(int) PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...); +VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3); +VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect); +VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect); +VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal); +VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect); + VMMDECL(int) PDMCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy); VMMDECL(int) PDMCritSectEnterDebug(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL); VMMDECL(int) PDMCritSectTryEnter(PPDMCRITSECT pCritSect); VMMDECL(int) PDMCritSectTryEnterDebug(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL); -VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3); VMMDECL(int) PDMCritSectLeave(PPDMCRITSECT pCritSect); + VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect); VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu); VMMDECL(bool) PDMCritSectIsInitialized(PCPDMCRITSECT pCritSect); VMMDECL(bool) PDMCritSectHasWaiters(PCPDMCRITSECT pCritSect); VMMDECL(uint32_t) PDMCritSectGetRecursion(PCPDMCRITSECT pCritSect); -VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect); -VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect); -VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal); -VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect); -VMMDECL(int) PDMR3CritSectTerm(PVM pVM); -VMMDECL(void) PDMCritSectFF(PVMCPU pVCpu); -VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames); -VMMR3DECL(void) PDMR3CritSectLeaveAll(PVM pVM); VMMR3DECL(PPDMCRITSECT) PDMR3CritSectGetNop(PVM pVM); VMMR3DECL(R0PTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopR0(PVM pVM); diff --git a/include/VBox/vmm/pdmcritsectrw.h b/include/VBox/vmm/pdmcritsectrw.h new file mode 100644 index 00000000..9c922017 --- /dev/null +++ b/include/VBox/vmm/pdmcritsectrw.h @@ -0,0 +1,97 @@ +/** @file + * PDM - Pluggable Device Manager, Read/Write Critical Section. + */ + +/* + * 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; + * 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 ___VBox_vmm_pdmcritsectrw_h +#define ___VBox_vmm_pdmcritsectrw_h + +#include + + +RT_C_DECLS_BEGIN + +/** @defgroup grp_pdm_critsectrw The PDM Read/Write Critical Section API + * @ingroup grp_pdm + * @{ + */ + +/** + * A PDM read/write critical section. + * Initialize using PDMDRVHLP::pfnCritSectRwInit(). + */ +typedef union PDMCRITSECTRW +{ + /** Padding. */ + uint8_t padding[HC_ARCH_BITS == 32 ? 0xc0 : 0x100]; +#ifdef PDMCRITSECTRWINT_DECLARED + /** The internal structure (not normally visible). */ + struct PDMCRITSECTRWINT s; +#endif +} PDMCRITSECTRW; + +VMMR3DECL(int) PDMR3CritSectRwInit(PVM pVM, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...); +VMMR3DECL(int) PDMR3CritSectRwDelete(PPDMCRITSECTRW pCritSect); +VMMR3DECL(const char *) PDMR3CritSectRwName(PCPDMCRITSECTRW pCritSect); +VMMR3DECL(int) PDMR3CritSectRwEnterSharedEx(PPDMCRITSECTRW pThis, bool fCallRing3); +VMMR3DECL(int) PDMR3CritSectRwEnterExclEx(PPDMCRITSECTRW pThis, bool fCallRing3); + +VMMDECL(int) PDMCritSectRwEnterShared(PPDMCRITSECTRW pCritSect, int rcBusy); +VMMDECL(int) PDMCritSectRwEnterSharedDebug(PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwTryEnterShared(PPDMCRITSECTRW pCritSect); +VMMDECL(int) PDMCritSectRwTryEnterSharedDebug(PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pCritSect); +VMMDECL(int) PDMCritSectRwEnterExcl(PPDMCRITSECTRW pCritSect, int rcBusy); +VMMDECL(int) PDMCritSectRwEnterExclDebug(PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwTryEnterExcl(PPDMCRITSECTRW pCritSect); +VMMDECL(int) PDMCritSectRwTryEnterExclDebug(PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pCritSect); + +VMMDECL(bool) PDMCritSectRwIsWriteOwner(PPDMCRITSECTRW pCritSect); +VMMDECL(bool) PDMCritSectRwIsReadOwner(PPDMCRITSECTRW pCritSect, bool fWannaHear); +VMMDECL(uint32_t) PDMCritSectRwGetWriteRecursion(PPDMCRITSECTRW pCritSect); +VMMDECL(uint32_t) PDMCritSectRwGetWriterReadRecursion(PPDMCRITSECTRW pCritSect); +VMMDECL(uint32_t) PDMCritSectRwGetReadCount(PPDMCRITSECTRW pCritSect); +VMMDECL(bool) PDMCritSectRwIsInitialized(PCPDMCRITSECTRW pCritSect); + +/* Lock strict build: Remap the three enter calls to the debug versions. */ +#ifdef VBOX_STRICT +# ifdef ___iprt_asm_h +# define PDMCritSectRwEnterExcl(pCritSect, rcBusy) PDMCritSectRwEnterExclDebug(pCritSect, rcBusy, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define PDMCritSectRwTryEnterExcl(pCritSect) PDMCritSectRwTryEnterExclDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define PDMCritSectRwEnterShared(pCritSect, rcBusy) PDMCritSectRwEnterSharedDebug(pCritSect, rcBusy, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define PDMCritSectRwTryEnterShared(pCritSect) PDMCritSectRwTryEnterSharedDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# else +# define PDMCritSectRwEnterExcl(pCritSect, rcBusy) PDMCritSectRwEnterExclDebug(pCritSect, rcBusy, 0, RT_SRC_POS) +# define PDMCritSectRwTryEnterExcl(pCritSect) PDMCritSectRwTryEnterExclDebug(pCritSect, 0, RT_SRC_POS) +# define PDMCritSectRwEnterShared(pCritSect, rcBusy) PDMCritSectRwEnterSharedDebug(pCritSect, rcBusy, 0, RT_SRC_POS) +# define PDMCritSectRwTryEnterShared(pCritSect) PDMCritSectRwTryEnterSharedDebug(pCritSect, 0, RT_SRC_POS) +# endif +#endif + +/** @} */ + +RT_C_DECLS_END + +#endif + diff --git a/include/VBox/vmm/pdmdev.h b/include/VBox/vmm/pdmdev.h index 892ed590..7a964b74 100644 --- a/include/VBox/vmm/pdmdev.h +++ b/include/VBox/vmm/pdmdev.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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; @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -107,30 +108,6 @@ typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDe /** Pointer to a FNPDMDEVRELOCATE() function. */ typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE; -/** - * Device I/O Control interface. - * - * This is used by external components, such as the COM interface, to - * communicate with devices using a class wide interface or a device - * specific interface. - * - * @returns VBox status code. - * @param pDevIns Pointer to the device instance. - * @param uFunction Function to perform. - * @param pvIn Pointer to input data. - * @param cbIn Size of input data. - * @param pvOut Pointer to output data. - * @param cbOut Size of output data. - * @param pcbOut Where to store the actual size of the output data. - * - * @remarks Not used. - */ -typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, uint32_t uFunction, - void *pvIn, uint32_t cbIn, - void *pvOut, uint32_t cbOut, PRTUINT pcbOut); -/** Pointer to a FNPDMDEVIOCTL() function. */ -typedef FNPDMDEVIOCTL *PFNPDMDEVIOCTL; - /** * Power On notification. * @@ -185,7 +162,7 @@ typedef FNPDMDEVRESUME *PFNPDMDEVRESUME; * * This is only called when the VMR3PowerOff call is made on a running VM. This * means that there is no notification if the VM was suspended before being - * powered of. There will also be no callback when hot plugging devices. + * powered off. There will also be no callback when hot plugging devices. * * @param pDevIns The device instance data. * @thread EMT(0) @@ -264,6 +241,21 @@ typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns); typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE; +/** + * The context of a pfnMemSetup call. + */ +typedef enum PDMDEVMEMSETUPCTX +{ + /** Invalid zero value. */ + PDMDEVMEMSETUPCTX_INVALID = 0, + /** After construction. */ + PDMDEVMEMSETUPCTX_AFTER_CONSTRUCTION, + /** After reset. */ + PDMDEVMEMSETUPCTX_AFTER_RESET, + /** Type size hack. */ + PDMDEVMEMSETUPCTX_32BIT_HACK = 0x7fffffff +} PDMDEVMEMSETUPCTX; + /** * PDM Device Registration Structure. @@ -304,9 +296,16 @@ typedef struct PDMDEVREG /** Relocation command - optional. * Critical section NOT entered. */ PFNPDMDEVRELOCATE pfnRelocate; - /** I/O Control interface - optional. - * Not used. */ - PFNPDMDEVIOCTL pfnIOCtl; + + /** + * Memory setup callback. + * + * @param pDevIns The device instance data. + * @param enmCtx Indicates the context of the call. + * @remarks The critical section is entered prior to calling this method. + */ + DECLR3CALLBACKMEMBER(void, pfnMemSetup, (PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx)); + /** Power on notification - optional. * Critical section is entered. */ PFNPDMDEVPOWERON pfnPowerOn; @@ -345,7 +344,7 @@ typedef PDMDEVREG *PPDMDEVREG; typedef PDMDEVREG const *PCPDMDEVREG; /** Current DEVREG version number. */ -#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 1, 0) +#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 2, 0) /** PDM Device Flags. * @{ */ @@ -503,6 +502,7 @@ typedef struct PDMPCIBUSREG * @param pszName Pointer to device name (permanent, readonly). For debugging, not unique. * @param iDev The device number ((dev << 3) | function) the device should have on the bus. * If negative, the pci bus device will assign one. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)); @@ -513,6 +513,7 @@ typedef struct PDMPCIBUSREG * @param pDevIns Device instance of the PCI Bus. * @param pPciDev The PCI device structure. * @param pMsiReg MSI registration structure + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg)); @@ -526,6 +527,7 @@ typedef struct PDMPCIBUSREG * @param cbRegion Size of the region. * @param iType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH. * @param pfnCallback Callback for doing the mapping. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); @@ -542,6 +544,7 @@ typedef struct PDMPCIBUSREG * @param pfnWriteOld Pointer to function pointer which will receive the old (default) * PCI config write function. This way, user can decide when (and if) * to call default PCI config write function. Can be NULL. + * @remarks Caller enters the PDM critical section. * @thread EMT */ DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, @@ -555,29 +558,10 @@ typedef struct PDMPCIBUSREG * @param iIrq IRQ number to set. * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)); - /** - * Saves a state of the PCI device. - * - * @returns VBox status code. - * @param pDevIns Device instance of the PCI Bus. - * @param pPciDev Pointer to PCI device. - * @param pSSMHandle The handle to save the state to. - */ - DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle)); - - /** - * Loads a saved PCI device state. - * - * @returns VBox status code. - * @param pDevIns Device instance of the PCI Bus. - * @param pPciDev Pointer to PCI device. - * @param pSSMHandle The handle to the saved state. - */ - DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle)); - /** * Called to perform the job of the bios. * This is only called for the first PCI Bus - it is expected to @@ -585,6 +569,7 @@ typedef struct PDMPCIBUSREG * * @returns VBox status. * @param pDevIns Device instance of the first bus. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns)); @@ -599,7 +584,7 @@ typedef struct PDMPCIBUSREG typedef PDMPCIBUSREG *PPDMPCIBUSREG; /** Current PDMPCIBUSREG version number. */ -#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 3, 0) +#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 4, 0) /** * PCI Bus RC helpers. @@ -858,6 +843,7 @@ typedef struct PDMPICREG * @param iIrq IRQ number to set. * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)); @@ -867,6 +853,7 @@ typedef struct PDMPICREG * @returns Pending interrupt number. * @param pDevIns Device instance of the PIC. * @param puTagSrc Where to return the IRQ tag and source. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); @@ -1077,40 +1064,52 @@ typedef struct PDMAPICREG * * @returns Pending interrupt number. * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. * @param puTagSrc Where to return the tag source. + * @remarks Caller enters the PDM critical section */ - DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); + DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t *puTagSrc)); /** * Check if the APIC has a pending interrupt/if a TPR change would active one * * @returns Pending interrupt yes/no * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. + * @param pu8PendingIrq Where to store the highest priority pending IRQ + * (optional, can be NULL). + * @remarks Unlike the other callbacks, the PDM lock may not always be entered + * prior to calling this method. */ - DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns)); + DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t *pu8PendingIrq)); /** * Set the APIC base. * * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. * @param u64Base The new base. + * @remarks Caller enters the PDM critical section. */ - DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base)); + DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint64_t u64Base)); /** * Get the APIC base. * * @returns Current base. * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. + * @remarks Caller enters the PDM critical section. */ - DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns)); + DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu)); /** * Set the TPR (task priority register). * * @param pDevIns Device instance of the APIC. - * @param idCpu VCPU id + * @param idCpu The VCPU id. * @param u8TPR The new TPR. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR)); @@ -1120,6 +1119,7 @@ typedef struct PDMAPICREG * @returns The current TPR. * @param pDevIns Device instance of the APIC. * @param idCpu VCPU id + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu)); @@ -1169,6 +1169,7 @@ typedef struct PDMAPICREG * @param u8Polarity See APIC implementation. * @param u8TriggerMode See APIC implementation. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)); @@ -1184,6 +1185,7 @@ typedef struct PDMAPICREG * @param u8Pin Local pin number (0 or 1 for current CPUs). * @param u8Level The level. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(int, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level)); @@ -1572,6 +1574,7 @@ typedef struct PDMIOAPICREG * @param iIrq IRQ number to set. * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)); @@ -1588,6 +1591,7 @@ typedef struct PDMIOAPICREG * @param GCPhys Request address. * @param uValue Request value. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)); @@ -2017,11 +2021,12 @@ typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3; * DMA Transfer Handler. * * @returns Number of bytes transferred. - * @param pDevIns Device instance of the DMA. - * @param pvUser User pointer. - * @param uChannel Channel number. - * @param off DMA position. - * @param cb Block size. + * @param pDevIns Device instance of the DMA. + * @param pvUser User pointer. + * @param uChannel Channel number. + * @param off DMA position. + * @param cb Block size. + * @remarks The device lock is not taken, however, the DMA device lock is held. */ typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb); /** Pointer to a FNDMATRANSFERHANDLER(). */ @@ -2040,6 +2045,7 @@ typedef struct PDMDMAREG * * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done. * @param pDevIns Device instance of the DMAC. + * @remarks No locks held, called on EMT(0) as a form of serialization. */ DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns)); @@ -2050,6 +2056,7 @@ typedef struct PDMDMAREG * @param uChannel Channel number. * @param pfnTransferHandler Device specific transfer function. * @param pvUSer User pointer to be passed to the callback. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)); @@ -2061,6 +2068,7 @@ typedef struct PDMDMAREG * @param pvBuffer Pointer to target buffer. * @param off DMA position. * @param cbBlock Block size. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock)); @@ -2072,6 +2080,7 @@ typedef struct PDMDMAREG * @param pvBuffer Memory to write. * @param off DMA position. * @param cbBlock Block size. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock)); @@ -2081,6 +2090,7 @@ typedef struct PDMDMAREG * @param pDevIns Device instance of the DMAC. * @param uChannel Channel number. * @param uLevel Level of the line. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)); @@ -2090,6 +2100,7 @@ typedef struct PDMDMAREG * @returns Channel mode. * @param pDevIns Device instance of the DMAC. * @param uChannel Channel number. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel)); @@ -2140,6 +2151,7 @@ typedef struct PDMRTCREG * @param pDevIns Device instance of the RTC. * @param iReg The CMOS register index. * @param u8Value The CMOS register value. + * @remarks Caller enters the device critical section. */ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)); @@ -2150,6 +2162,7 @@ typedef struct PDMRTCREG * @param pDevIns Device instance of the RTC. * @param iReg The CMOS register index. * @param pu8Value Where to store the CMOS register value. + * @remarks Caller enters the device critical section. */ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)); @@ -2160,7 +2173,7 @@ typedef PDMRTCREG *PPDMRTCREG; typedef const PDMRTCREG *PCPDMRTCREG; /** Current PDMRTCREG version number. */ -#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 1, 0) +#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 2, 0) /** @@ -2211,6 +2224,8 @@ typedef struct PDMDEVHLPR3 * @param pfnOutStr Pointer to function which is gonna handle string OUT operations. * @param pfnInStr Pointer to function which is gonna handle string IN operations. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, @@ -2235,6 +2250,8 @@ typedef struct PDMDEVHLPR3 * @param pszOutStr Name of the RC function which is gonna handle string OUT operations. * @param pszInStr Name of the RC function which is gonna handle string IN operations. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser, const char *pszOut, const char *pszIn, @@ -2256,6 +2273,8 @@ typedef struct PDMDEVHLPR3 * @param pszOutStr Name of the R0 function which is gonna handle string OUT operations. * @param pszInStr Name of the R0 function which is gonna handle string IN operations. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser, const char *pszOut, const char *pszIn, @@ -2290,6 +2309,8 @@ typedef struct PDMDEVHLPR3 * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional) * @param fFlags Flags, IOMMMIO_FLAGS_XXX. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, @@ -2310,6 +2331,8 @@ typedef struct PDMDEVHLPR3 * @param pszWrite Name of the RC function which is gonna handle Write operations. * @param pszRead Name of the RC function which is gonna handle Read operations. * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional) + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser, const char *pszWrite, const char *pszRead, const char *pszFill)); @@ -2330,6 +2353,8 @@ typedef struct PDMDEVHLPR3 * @param pszRead Name of the RC function which is gonna handle Read operations. * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional) * @param pszDesc Obsolete. NULL is fine. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser, const char *pszWrite, const char *pszRead, const char *pszFill)); @@ -2512,6 +2537,8 @@ typedef struct PDMDEVHLPR3 * @param pfnLoadPrep Prepare load callback, optional. * @param pfnLoadExec Execute load callback, optional. * @param pfnLoadDone Done load callback, optional. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore, PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, @@ -2530,6 +2557,8 @@ typedef struct PDMDEVHLPR3 * @param pszDesc Pointer to description string which must stay around * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()). * @param ppTimer Where to store the timer on success. + * @remarks Caller enters the device critical section prior to invoking the + * callback. */ DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)); @@ -2796,6 +2825,22 @@ typedef struct PDMDEVHLPR3 */ DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)); + /** + * Registers a set of registers for a device. + * + * The @a pvUser argument of the getter and setter callbacks will be + * @a pDevIns. The register names will be prefixed by the device name followed + * immediately by the instance number. + * + * @returns VBox status code. + * @param pDevIns The device instance. + * @param paRegisters The register descriptors. + * + * @remarks The device critical section is NOT entered prior to working the + * callbacks registered via this helper! + */ + DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)); + /** * Gets the trace buffer handle. * @@ -2860,22 +2905,6 @@ typedef struct PDMDEVHLPR3 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)); - /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. - * - * @return IPRT status code. - */ - DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); - - /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. - * - * @return IPRT status code. - */ - DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); - /** * Registers the device with the default PCI bus. * @@ -2907,8 +2936,11 @@ typedef struct PDMDEVHLPR3 * @param cbRegion Size of the region. * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH. * @param pfnCallback Callback for doing the mapping. + * @remarks The callback will be invoked holding the PDM lock. The device lock + * is NOT take because that is very likely be a lock order violation. */ - DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); + DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, + PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); /** * Register PCI configuration space read/write callbacks. @@ -2924,11 +2956,39 @@ typedef struct PDMDEVHLPR3 * @param pfnWriteOld Pointer to function pointer which will receive the old (default) * PCI config write function. This way, user can decide when (and if) * to call default PCI config write function. Can be NULL. + * @remarks The callbacks will be invoked holding the PDM lock. The device lock + * is NOT take because that is very likely be a lock order violation. * @thread EMT */ DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)); + /** + * Bus master physical memory read. + * + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address start reading from. + * @param pvBuf Where to put the read bits. + * @param cbRead How many bytes to read. + * @thread Any thread, but the call may involve the emulation thread. + */ + DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); + + /** + * Bus master physical memory write. + * + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address to write to. + * @param pvBuf What to write. + * @param cbWrite How many bytes to write. + * @thread Any thread, but the call may involve the emulation thread. + */ + DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); + /** * Set the IRQ for a PCI device. * @@ -2985,7 +3045,8 @@ typedef struct PDMDEVHLPR3 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid * for the live of the device instance. */ - DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)); + DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, + PPDMIBASE *ppBaseInterface, const char *pszDesc)); /** * Create a queue. @@ -3002,6 +3063,9 @@ typedef struct PDMDEVHLPR3 * appended automatically. * @param ppQueue Where to store the queue handle on success. * @thread The emulation thread. + * @remarks The device critical section will NOT be entered before calling the + * callback. No locks will be held, but for now it's safe to assume + * that only one EMT will do queue callbacks at any one time. */ DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue)); @@ -3075,6 +3139,8 @@ typedef struct PDMDEVHLPR3 * @param cbStack See RTThreadCreate. * @param enmType See RTThreadCreate. * @param pszName See RTThreadCreate. + * @remarks The device critical section will NOT be entered prior to invoking + * the function pointers. */ DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)); @@ -3089,6 +3155,8 @@ typedef struct PDMDEVHLPR3 * @param pDevIns The device instance. * @param pfnAsyncNotify The callback. * @thread EMT(0) + * @remarks The caller will enter the device critical section prior to invoking + * the callback. */ DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)); @@ -3372,6 +3440,25 @@ typedef struct PDMDEVHLPR3 */ DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)); + /** + * Gets the reason for the most recent VM suspend. + * + * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no + * suspend has been made or if the pDevIns is invalid. + * @param pDevIns The device instance. + */ + DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns)); + + /** + * Gets the reason for the most recent VM resume. + * + * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no + * resume has been made or if the pDevIns is invalid. + * @param pDevIns The device instance. + */ + DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns)); + + /** Space reserved for future members. * @{ */ DECLR3CALLBACKMEMBER(void, pfnReserved1,(void)); @@ -3381,9 +3468,9 @@ typedef struct PDMDEVHLPR3 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void)); DECLR3CALLBACKMEMBER(void, pfnReserved6,(void)); DECLR3CALLBACKMEMBER(void, pfnReserved7,(void)); - DECLR3CALLBACKMEMBER(void, pfnReserved8,(void)); - DECLR3CALLBACKMEMBER(void, pfnReserved9,(void)); - DECLR3CALLBACKMEMBER(void, pfnReserved10,(void)); + /*DECLR3CALLBACKMEMBER(void, pfnReserved8,(void)); + DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));*/ + /*DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));*/ /** @} */ @@ -3394,8 +3481,17 @@ typedef struct PDMDEVHLPR3 * * @{ */ + /** - * Gets the VM handle. Restricted API. + * Gets the user mode VM handle. Restricted API. + * + * @returns User mode VM Handle. + * @param pDevIns The device instance. + */ + DECLR3CALLBACKMEMBER(PUVM, pfnGetUVM,(PPDMDEVINS pDevIns)); + + /** + * Gets the global VM handle. Restricted API. * * @returns VM Handle. * @param pDevIns The device instance. @@ -3527,6 +3623,16 @@ typedef struct PDMDEVHLPR3 */ DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns)); + /** + * Gets the support driver session. + * + * This is intended for working with the semaphore API. + * + * @returns Support driver session handle. + * @param pDrvIns The driver instance. + */ + DECLR3CALLBACKMEMBER(PSUPDRVSESSION, pfnGetSupDrvSession,(PPDMDEVINS pDevIns)); + /** @} */ /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */ @@ -3539,7 +3645,7 @@ typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3; typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3; /** Current PDMDEVHLPR3 version number. */ -#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 9, 0) +#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 12, 1) /** @@ -3551,20 +3657,30 @@ typedef struct PDMDEVHLPRC uint32_t u32Version; /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. + * Bus master physical memory read. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address start reading from. + * @param pvBuf Where to put the read bits. + * @param cbRead How many bytes to read. + * @thread Any thread, but the call may involve the emulation thread. */ - DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); + DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. + * Bus master physical memory write. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address to write to. + * @param pvBuf What to write. + * @param cbWrite How many bytes to write. + * @thread Any thread, but the call may involve the emulation thread. */ - DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); + DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); /** * Set the IRQ for a PCI device. @@ -3746,7 +3862,7 @@ typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC; typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC; /** Current PDMDEVHLP version number. */ -#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 0) +#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 1) /** @@ -3758,18 +3874,28 @@ typedef struct PDMDEVHLPR0 uint32_t u32Version; /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. + * Bus master physical memory read. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe + * VERR_EM_MEMORY. + * @param pDevIns The device instance. + * @param GCPhys Physical address start reading from. + * @param pvBuf Where to put the read bits. + * @param cbRead How many bytes to read. + * @thread Any thread, but the call may involve the emulation thread. */ DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. + * Bus master physical memory write. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe + * VERR_EM_MEMORY. + * @param pDevIns The device instance. + * @param GCPhys Physical address to write to. + * @param pvBuf What to write. + * @param cbWrite How many bytes to write. + * @thread Any thread, but the call may involve the emulation thread. */ DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); @@ -3961,7 +4087,7 @@ typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0; typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0; /** Current PDMDEVHLP version number. */ -#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 0) +#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 1) @@ -4620,6 +4746,14 @@ DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszNam return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler); } +/** + * @copydoc PDMDEVHLPR3::pfnDBGFRegRegister + */ +DECLINLINE(int) PDMDevHlpDBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters) +{ + return pDevIns->pHlpR3->pfnDBGFRegRegister(pDevIns, paRegisters); +} + /** * @copydoc PDMDEVHLPR3::pfnSTAMRegister */ @@ -4673,56 +4807,24 @@ DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE p pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld); } +#endif /* IN_RING3 */ + /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. - * - * @return IPRT status code. + * @copydoc PDMDEVHLPR3::pfnPCIPhysRead */ -DECLINLINE(int) PDMDevHlpPCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) +DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) { - AssertPtrReturn(pPciDev, VERR_INVALID_POINTER); - AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); - AssertReturn(cbRead, VERR_INVALID_PARAMETER); - - if (!PCIDevIsBusmaster(pPciDev)) - { -#ifdef DEBUG - Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__, - PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead)); -#endif - return VINF_PDM_PCI_PHYS_READ_BM_DISABLED; - } - - return PDMDevHlpPhysRead(pPciDev->pDevIns, GCPhys, pvBuf, cbRead); + return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, GCPhys, pvBuf, cbRead); } /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. - * - * @return IPRT status code. + * @copydoc PDMDEVHLPR3::pfnPCIPhysWrite */ -DECLINLINE(int) PDMDevHlpPCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) +DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) { - AssertPtrReturn(pPciDev, VERR_INVALID_POINTER); - AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); - AssertReturn(cbWrite, VERR_INVALID_PARAMETER); - - if (!PCIDevIsBusmaster(pPciDev)) - { -#ifdef DEBUG - Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__, - PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite)); -#endif - return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED; - } - - return PDMDevHlpPhysWrite(pPciDev->pDevIns, GCPhys, pvBuf, cbWrite); + return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite); } -#endif /* IN_RING3 */ - /** * @copydoc PDMDEVHLPR3::pfnPCISetIrq */ @@ -4999,6 +5101,30 @@ DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_ return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg); } +/** + * @copydoc PDMDEVHLP::pfnVMGetSuspendReason + */ +DECLINLINE(VMSUSPENDREASON) PDMDevHlpVMGetSuspendReason(PPDMDEVINS pDevIns) +{ + return pDevIns->pHlpR3->pfnVMGetSuspendReason(pDevIns); +} + +/** + * @copydoc PDMDEVHLP::pfnVMGetResumeReason + */ +DECLINLINE(VMRESUMEREASON) PDMDevHlpVMGetResumeReason(PPDMDEVINS pDevIns) +{ + return pDevIns->pHlpR3->pfnVMGetResumeReason(pDevIns); +} + +/** + * @copydoc PDMDEVHLPR3::pfnGetUVM + */ +DECLINLINE(PUVM) PDMDevHlpGetUVM(PPDMDEVINS pDevIns) +{ + return pDevIns->CTX_SUFF(pHlp)->pfnGetUVM(pDevIns); +} + #endif /* IN_RING3 */ /** @@ -5111,6 +5237,14 @@ DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx); } +/** + * @copydoc PDMDEVHLPR3::pfnGetSupDrvSession + */ +DECLINLINE(PSUPDRVSESSION) PDMDevHlpGetSupDrvSession(PPDMDEVINS pDevIns) +{ + return pDevIns->pHlpR3->pfnGetSupDrvSession(pDevIns); +} + #endif /* IN_RING3 */ #ifdef IN_RING0 diff --git a/include/VBox/vmm/pdmdrv.h b/include/VBox/vmm/pdmdrv.h index d830ea69..57dbe960 100644 --- a/include/VBox/vmm/pdmdrv.h +++ b/include/VBox/vmm/pdmdrv.h @@ -3,7 +3,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; @@ -1297,12 +1297,43 @@ typedef struct PDMDRVHLPR3 PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue, PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard, const char *pcszId)); + /** + * Gets the reason for the most recent VM suspend. + * + * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no + * suspend has been made or if the pDrvIns is invalid. + * @param pDrvIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDRVINS pDrvIns)); + + /** + * Gets the reason for the most recent VM resume. + * + * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no + * resume has been made or if the pDrvIns is invalid. + * @param pDrvIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDRVINS pDrvIns)); + + /** @name Space reserved for minor interface changes. + * @{ */ + DECLR3CALLBACKMEMBER(void, pfnReserved0,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved1,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved2,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved3,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved4,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved5,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved6,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved7,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved8,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved9,(PPDMDRVINS pDrvIns)); + /** @} */ /** Just a safety precaution. */ uint32_t u32TheEnd; } PDMDRVHLPR3; /** Current DRVHLP version number. */ -#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 2, 0) +#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 3, 0) #endif /* IN_RING3 */ @@ -1777,6 +1808,23 @@ DECLINLINE(int) PDMDrvHlpBlkCacheRetain(PPDMDRVINS pDrvIns, PPPDMBLKCACHE ppBlkC return pDrvIns->pHlpR3->pfnBlkCacheRetain(pDrvIns, ppBlkCache, pfnXferComplete, pfnXferEnqueue, pfnXferEnqueueDiscard, pcszId); } +/** + * @copydoc PDMDRVHLP::pfnVMGetSuspendReason + */ +DECLINLINE(VMSUSPENDREASON) PDMDrvHlpVMGetSuspendReason(PPDMDRVINS pDrvIns) +{ + return pDrvIns->pHlpR3->pfnVMGetSuspendReason(pDrvIns); +} + +/** + * @copydoc PDMDRVHLP::pfnVMGetResumeReason + */ +DECLINLINE(VMRESUMEREASON) PDMDrvHlpVMGetResumeReason(PPDMDRVINS pDrvIns) +{ + return pDrvIns->pHlpR3->pfnVMGetResumeReason(pDrvIns); +} + + /** Pointer to callbacks provided to the VBoxDriverRegister() call. */ typedef struct PDMDRVREGCB *PPDMDRVREGCB; /** Pointer to const callbacks provided to the VBoxDriverRegister() call. */ diff --git a/include/VBox/vmm/pdmifs.h b/include/VBox/vmm/pdmifs.h index 17dba105..913c0dc2 100644 --- a/include/VBox/vmm/pdmifs.h +++ b/include/VBox/vmm/pdmifs.h @@ -296,14 +296,16 @@ typedef struct PDMIMOUSEPORT * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the * event now and want it to be repeated at a later point. * - * @param pInterface Pointer to this interface structure. - * @param iDeltaX The X delta. - * @param iDeltaY The Y delta. - * @param iDeltaZ The Z delta. - * @param iDeltaW The W (horizontal scroll button) delta. - * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. + * @param pInterface Pointer to this interface structure. + * @param dx The X delta. + * @param dy The Y delta. + * @param dz The Z delta. + * @param dw The W (horizontal scroll button) delta. + * @param fButtons The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. */ - DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface, int32_t iDeltaX, int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates)); + DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface, + int32_t dx, int32_t dy, int32_t dz, + int32_t dw, uint32_t fButtons)); /** * Puts an absolute mouse event. * @@ -313,17 +315,45 @@ typedef struct PDMIMOUSEPORT * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the * event now and want it to be repeated at a later point. * - * @param pInterface Pointer to this interface structure. - * @param uX The X value, in the range 0 to 0xffff. - * @param uY The Y value, in the range 0 to 0xffff. - * @param iDeltaZ The Z delta. - * @param iDeltaW The W (horizontal scroll button) delta. - * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. + * @param pInterface Pointer to this interface structure. + * @param x The X value, in the range 0 to 0xffff. + * @param z The Y value, in the range 0 to 0xffff. + * @param dz The Z delta. + * @param dw The W (horizontal scroll button) delta. + * @param fButtons The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. */ - DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates)); + DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface, + uint32_t x, uint32_t z, + int32_t dz, int32_t dw, + uint32_t fButtons)); + /** + * Puts a multi-touch event. + * + * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the + * event now and want it to be repeated at a later point. + * + * @param pInterface Pointer to this interface structure. + * @param cContacts How many touch contacts in this event. + * @param pau64Contacts Pointer to array of packed contact information. + * Each 64bit element contains: + * Bits 0..15: X coordinate in pixels (signed). + * Bits 16..31: Y coordinate in pixels (signed). + * Bits 32..39: contact identifier. + * Bit 40: "in contact" flag, which indicates that + * there is a contact with the touch surface. + * Bit 41: "in range" flag, the contact is close enough + * to the touch surface. + * All other bits are reserved for future use and must be set to 0. + * @param u32ScanTime Timestamp of this event in milliseconds. Only relative + * time between event is important. + */ + DECLR3CALLBACKMEMBER(int, pfnPutEventMultiTouch,(PPDMIMOUSEPORT pInterface, + uint8_t cContacts, + const uint64_t *pau64Contacts, + uint32_t u32ScanTime)); } PDMIMOUSEPORT; /** PDMIMOUSEPORT interface ID. */ -#define PDMIMOUSEPORT_IID "442136fe-6f3c-49ec-9964-259b378ffa64" +#define PDMIMOUSEPORT_IID "359364f0-9fa3-4490-a6b4-7ed771901c93" /** Mouse button defines for PDMIMOUSEPORT::pfnPutEvent. * @{ */ @@ -350,8 +380,9 @@ typedef struct PDMIMOUSECONNECTOR * @param pInterface Pointer to the this interface. * @param fRelative Whether relative mode is currently supported. * @param fAbsolute Whether absolute mode is currently supported. + * @param fAbsolute Whether multi-touch mode is currently supported. */ - DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute)); + DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute, bool fMultiTouch)); } PDMIMOUSECONNECTOR; /** PDMIMOUSECONNECTOR interface ID. */ @@ -598,8 +629,11 @@ typedef struct VBVAHOSTFLAGS *PVBVAHOSTFLAGS; typedef struct VBOXVDMACMD_CHROMIUM_CMD *PVBOXVDMACMD_CHROMIUM_CMD; /* <- chromium [hgsmi] command */ typedef struct VBOXVDMACMD_CHROMIUM_CTL *PVBOXVDMACMD_CHROMIUM_CTL; /* <- chromium [hgsmi] command */ + /** Pointer to a display connector interface. */ typedef struct PDMIDISPLAYCONNECTOR *PPDMIDISPLAYCONNECTOR; +struct VBOXCRCMDCTL; +typedef DECLCALLBACKPTR(void, PFNCRCTLCOMPLETION)(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion); /** * Display connector interface (up). * Pair with PDMIDISPLAYPORT. @@ -703,9 +737,12 @@ typedef struct PDMIDISPLAYCONNECTOR * * @param pInterface Pointer to this interface. * @param pCmd Video HW Acceleration Command to be processed. + * @returns VINF_SUCCESS - command is completed, + * VINF_CALLBACK_RETURN - command will by asynchronously completed via complete callback + * VERR_INVALID_STATE - the command could not be processed (most likely because the framebuffer was disconnected) - the post should be retried later * @thread The emulation thread. */ - DECLR3CALLBACKMEMBER(void, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd)); + DECLR3CALLBACKMEMBER(int, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd)); /** * Process the guest chromium command. @@ -725,6 +762,17 @@ typedef struct PDMIDISPLAYCONNECTOR */ DECLR3CALLBACKMEMBER(void, pfnCrHgsmiControlProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl)); + /** + * Process the guest chromium control command. + * + * @param pInterface Pointer to this interface. + * @param pCmd Video HW Acceleration Command to be processed. + * @thread The emulation thread. + */ + DECLR3CALLBACKMEMBER(int, pfnCrHgcmCtlSubmit, (PPDMIDISPLAYCONNECTOR pInterface, + struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, + PFNCRCTLCOMPLETION pfnCompletion, + void *pvCompletion)); /** * The specified screen enters VBVA mode. @@ -835,7 +883,7 @@ typedef struct PDMIDISPLAYCONNECTOR /** @} */ } PDMIDISPLAYCONNECTOR; /** PDMIDISPLAYCONNECTOR interface ID. */ -#define PDMIDISPLAYCONNECTOR_IID "c7a1b36d-8dfc-421d-b71f-3a0eeaf733e6" +#define PDMIDISPLAYCONNECTOR_IID "05ba9649-302e-43dd-b9ff-60b6fb311d97" /** Pointer to a block port interface. */ @@ -892,6 +940,12 @@ typedef enum PDMBLOCKTYPE PDMBLOCKTYPE_FLOPPY_1_44, /** 2.88MB 3 1/2" floppy drive. */ PDMBLOCKTYPE_FLOPPY_2_88, + /** Fake drive that can take up to 15.6 MB images. + * C=255, H=2, S=63. */ + PDMBLOCKTYPE_FLOPPY_FAKE_15_6, + /** Fake drive that can take up to 63.5 MB images. + * C=255, H=2, S=255. */ + PDMBLOCKTYPE_FLOPPY_FAKE_63_5, /** CDROM drive. */ PDMBLOCKTYPE_CDROM, /** DVD drive. */ @@ -900,6 +954,8 @@ typedef enum PDMBLOCKTYPE PDMBLOCKTYPE_HARD_DISK } PDMBLOCKTYPE; +/** Check if the given block type is a floppy. */ +#define PDMBLOCKTYPE_IS_FLOPPY(a_enmType) ( (a_enmType) >= PDMBLOCKTYPE_FLOPPY_360 && (a_enmType) <= PDMBLOCKTYPE_FLOPPY_2_88 ) /** * Block raw command data transfer direction. @@ -999,6 +1055,15 @@ typedef struct PDMIBLOCK */ DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIBLOCK pInterface)); + /** + * Gets the media sector size in bytes. + * + * @returns Media sector size in bytes. + * @param pInterface Pointer to the interface structure containing the called function pointer. + * @thread Any thread. + */ + DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIBLOCK pInterface)); + /** * Gets the block drive type. * @@ -1244,6 +1309,15 @@ typedef struct PDMIMEDIA */ DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIMEDIA pInterface)); + /** + * Gets the media sector size in bytes. + * + * @returns Media sector size in bytes. + * @param pInterface Pointer to the interface structure containing the called function pointer. + * @thread Any thread. + */ + DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIMEDIA pInterface)); + /** * Check if the media is readonly or not. * @@ -2065,8 +2139,19 @@ typedef struct PDMIVMMDEVPORT * @param cy Vertical pixel resolution (0 = do not change). * @param cBits Bits per pixel (0 = do not change). * @param idxDisplay The display index. + * @param xOrigin The X coordinate of the lower left + * corner of the secondary display with + * ID = idxDisplay + * @param yOrigin The Y coordinate of the lower left + * corner of the secondary display with + * ID = idxDisplay + * @param fEnabled Whether the display is enabled or not. (Guessing + * again.) + * @param fChangeOrigin Whether the display origin point changed. (Guess) */ - DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay)); + DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx, + uint32_t cy, uint32_t cBits, uint32_t idxDisplay, + int32_t xOrigin, int32_t yOrigin, bool fEnabled, bool fChangeOrigin)); /** * Pass credentials to guest. @@ -2236,6 +2321,23 @@ typedef struct PDMIVMMDEVCONNECTOR DECLR3CALLBACKMEMBER(void, pfnUpdateGuestStatus,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t uFacility, uint16_t uStatus, uint32_t fFlags, PCRTTIMESPEC pTimeSpecTS)); + /** + * Updates a guest user state. + * + * Called in response to VMMDevReq_ReportGuestUserState. + * + * @param pInterface Pointer to this interface. + * @param pszUser Guest user name to update status for. + * @param pszDomain Domain the guest user is bound to. Optional. + * @param uState New guest user state to notify host about. + * @param puDetails Pointer to optional state data. + * @param cbDetails Size (in bytes) of optional state data. + * @thread The emulation thread. + */ + DECLR3CALLBACKMEMBER(void, pfnUpdateGuestUserState,(PPDMIVMMDEVCONNECTOR pInterface, const char *pszUser, const char *pszDomain, + uint32_t uState, + const uint8_t *puDetails, uint32_t cbDetails)); + /** * Reports the guest API and OS version. * Called whenever the Additions issue a guest info report request. @@ -2966,6 +3068,11 @@ typedef struct PDMIDISPLAYVBVACALLBACKS DECLR3CALLBACKMEMBER(int, pfnCrHgsmiControlCompleteAsync, (PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc)); + + DECLR3CALLBACKMEMBER(int, pfnCrCtlSubmit, (PPDMIDISPLAYVBVACALLBACKS pInterface, + struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, + PFNCRCTLCOMPLETION pfnCompletion, + void *pvCompletion)); } PDMIDISPLAYVBVACALLBACKS; /** PDMIDISPLAYVBVACALLBACKS */ #define PDMIDISPLAYVBVACALLBACKS_IID "b78b81d2-c821-4e66-96ff-dbafa76343a5" diff --git a/include/VBox/vmm/pdmnetinline.h b/include/VBox/vmm/pdmnetinline.h index 66c3078f..ac2bb6f7 100644 --- a/include/VBox/vmm/pdmnetinline.h +++ b/include/VBox/vmm/pdmnetinline.h @@ -6,7 +6,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/include/VBox/vmm/pdmnetshaper.h b/include/VBox/vmm/pdmnetshaper.h index b2aa5bab..d3610564 100644 --- a/include/VBox/vmm/pdmnetshaper.h +++ b/include/VBox/vmm/pdmnetshaper.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011-2012 Oracle Corporation + * Copyright (C) 2011-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; @@ -33,84 +33,43 @@ #include -#define PDM_NETSHAPER_MIN_BUCKET_SIZE 65536 /* bytes */ -#define PDM_NETSHAPER_MAX_LATENCY 100 /* milliseconds */ +/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API + * @ingroup grp_pdm + * @{ + */ + + +#define PDM_NETSHAPER_MIN_BUCKET_SIZE UINT32_C(65536) /**< bytes */ +#define PDM_NETSHAPER_MAX_LATENCY UINT32_C(100) /**< milliseconds */ RT_C_DECLS_BEGIN typedef struct PDMNSFILTER { - /** [R3] Pointer to the next group in the list. */ - struct PDMNSFILTER *pNext; - /** [R3] Pointer to the bandwidth group. */ - struct PDMNSBWGROUP *pBwGroupR3; - /** [R0] Pointer to the bandwidth group. */ - R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0; - /** Becomes true when filter fails to obtain bandwidth. */ - bool fChoked; - /** [R3] The driver this filter is aggregated into. */ - PPDMINETWORKDOWN pIDrvNet; + /** Pointer to the next group in the list (ring-3). */ + R3PTRTYPE(struct PDMNSFILTER *) pNextR3; + /** Pointer to the bandwidth group (ring-3). */ + R3PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR3; + /** Pointer to the bandwidth group (ring-0). */ + R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0; + /** Set when the filter fails to obtain bandwidth. */ + bool fChoked; + /** Aligment padding. */ + bool afPadding[HC_ARCH_BITS == 32 ? 3 : 7]; + /** The driver this filter is aggregated into (ring-3). */ + R3PTRTYPE(PPDMINETWORKDOWN) pIDrvNetR3; } PDMNSFILTER; -/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API - * @ingroup grp_pdm - * @{ - */ - /** Pointer to a PDM filter handle. */ typedef struct PDMNSFILTER *PPDMNSFILTER; /** Pointer to a network shaper. */ typedef struct PDMNETSHAPER *PPDMNETSHAPER; -/** - * Obtain bandwidth in a bandwidth group (R0 version). - * - * @returns VBox status code. - * @param pFilter Pointer to the filter that allocates bandwidth. - * @param cbTransfer Number of bytes to allocate. - */ -VMMR0DECL(bool) PDMR0NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer); - -/** - * Obtain bandwidth in a bandwidth group. - * - * @returns VBox status code. - * @param pFilter Pointer to the filter that allocates bandwidth. - * @param cbTransfer Number of bytes to allocate. - */ -VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer); - -/** - * Attach network filter driver from bandwidth group. - * - * @returns VBox status code. - * @param pVM Handle of VM. - * @param pDrvIns The driver instance. - * @param pcszBwGroup Name of the bandwidth group to attach to. - * @param pFilter Pointer to the filter we attach. - */ -VMMR3DECL(int) PDMR3NsAttach(PVM pVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter); - -/** - * Detach network filter driver from bandwidth group. - * - * @returns VBox status code. - * @param pVM Handle of VM. - * @param pDrvIns The driver instance. - * @param pFilter Pointer to the filter we detach. - */ -VMMR3DECL(int) PDMR3NsDetach(PVM pVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter); - -/** - * Adjusts the maximum rate for the bandwidth group. - * - * @returns VBox status code. - * @param pVM Handle of VM. - * @param pcszBwGroup Name of the bandwidth group to attach to. - * @param cbTransferPerSecMax Maximum number of bytes per second to be transmitted. - */ -VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PVM pVM, const char *pcszBwGroup, uint64_t cbTransferPerSecMax); +VMMDECL(bool) PDMNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer); +VMMR3_INT_DECL(int) PDMR3NsAttach(PUVM pUVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter); +VMMR3_INT_DECL(int) PDMR3NsDetach(PUVM pUVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter); +VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PUVM pUVM, const char *pszBwGroup, uint64_t cbPerSecMax); /** @} */ diff --git a/include/VBox/vmm/pdmnetshaperint.h b/include/VBox/vmm/pdmnetshaperint.h deleted file mode 100644 index 3bbfcda7..00000000 --- a/include/VBox/vmm/pdmnetshaperint.h +++ /dev/null @@ -1,94 +0,0 @@ -/* $Id: pdmnetshaperint.h $ */ -/** @file - * PDM Network Shaper - Internal data structures and functions common for both - * R0 and R3 parts. - */ - -/* - * Copyright (C) 2011-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. - */ - -/** - * Bandwidth group instance data - */ -typedef struct PDMNSBWGROUP -{ - /** Pointer to the next group in the list. */ - struct PDMNSBWGROUP *pNext; - /** Pointer to the shared UVM structure. */ - struct PDMNETSHAPER *pShaper; - /** Critical section protecting all members below. */ - PDMCRITSECT cs; - /** Pointer to the first filter attached to this group. */ - struct PDMNSFILTER *pFiltersHead; - /** Bandwidth group name. */ - char *pszName; - /** Maximum number of bytes filters are allowed to transfer. */ - volatile uint64_t cbTransferPerSecMax; - /** Number of bytes we are allowed to transfer in one burst. */ - volatile uint32_t cbBucketSize; - /** Number of bytes we were allowed to transfer at the last update. */ - volatile uint32_t cbTokensLast; - /** Timestamp of the last update */ - volatile uint64_t tsUpdatedLast; - /** Reference counter - How many filters are associated with this group. */ - volatile uint32_t cRefs; -} PDMNSBWGROUP; -/** Pointer to a bandwidth group. */ -typedef PDMNSBWGROUP *PPDMNSBWGROUP; - -DECLINLINE(bool) pdmNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer) -{ - AssertPtrReturn(pFilter, true); - if (!VALID_PTR(pFilter->CTX_SUFF(pBwGroup))) - return true; - - PPDMNSBWGROUP pBwGroup = ASMAtomicReadPtrT(&pFilter->CTX_SUFF(pBwGroup), PPDMNSBWGROUP); - int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); - if (RT_UNLIKELY(rc == VERR_SEM_BUSY)) - return true; - bool fAllowed = true; - if (pBwGroup->cbTransferPerSecMax) - { - /* Re-fill the bucket first */ - uint64_t tsNow = RTTimeSystemNanoTS(); - uint32_t uTokensAdded = (tsNow - pBwGroup->tsUpdatedLast)*pBwGroup->cbTransferPerSecMax/(1000*1000*1000); - uint32_t uTokens = RT_MIN(pBwGroup->cbBucketSize, uTokensAdded + pBwGroup->cbTokensLast); - - if (cbTransfer > uTokens) - { - fAllowed = false; - ASMAtomicWriteBool(&pFilter->fChoked, true); - } - else - { - pBwGroup->tsUpdatedLast = tsNow; - pBwGroup->cbTokensLast = uTokens - (uint32_t)cbTransfer; - } - Log2((LOG_FN_FMT "BwGroup=%#p{%s} cbTransfer=%u uTokens=%u uTokensAdded=%u fAllowed=%RTbool\n", - __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, cbTransfer, uTokens, uTokensAdded, fAllowed)); - } - else - Log2((LOG_FN_FMT "BwGroup=%#p{%s} disabled fAllowed=%RTbool\n", - __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, fAllowed)); - - rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); - return fAllowed; -} diff --git a/include/VBox/vmm/pdmnvram.h b/include/VBox/vmm/pdmnvram.h index 10c1abc4..03967dff 100644 --- a/include/VBox/vmm/pdmnvram.h +++ b/include/VBox/vmm/pdmnvram.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2012 Oracle Corporation + * Copyright (C) 2012-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; @@ -36,35 +36,85 @@ RT_C_DECLS_BEGIN * @{ */ -typedef struct PDMINVRAM *PPDMINVRAM; +/** Pointer to NVRAM interface provided by the driver. */ +typedef struct PDMINVRAMCONNECTOR *PPDMINVRAMCONNECTOR; -typedef struct PDMINVRAM +/** + * Non-volatile RAM storage interface provided by the driver (up). + * + * @note The variable indexes used here 0-based, sequential and without gaps. + */ +typedef struct PDMINVRAMCONNECTOR { /** - * This method flushes all values in the storage. + * Query a variable by variable index. + * + * @returns VBox status code. + * @retval VERR_NOT_FOUND if the variable was not found. This indicates that + * there are not variables with a higher index. + * + * @param idxVariable The variable index. By starting @a idxVariable at 0 + * and increasing it with each call, this can be used + * to enumerate all available variables. + * @param pVendorUuid The vendor UUID of the variable. + * @param pszName The variable name buffer. + * @param pcchName On input this hold the name buffer size (including + * the space for the terminator char). On successful + * return it holds the strlen() value for @a pszName. + * @param pfAttributes Where to return the value attributes. + * @param pbValue The value buffer. + * @param pcbValue On input the size of the value buffer, on output the + * actual number of bytes returned. */ - DECLR3CALLBACKMEMBER(int, pfnFlushNvramStorage, (PPDMINVRAM pInterface)); + DECLR3CALLBACKMEMBER(int, pfnVarQueryByIndex,(PPDMINVRAMCONNECTOR pInterface, uint32_t idxVariable, + PRTUUID pVendorUuid, char *pszName, uint32_t *pcchName, + uint32_t *pfAttributes, uint8_t *pbValue, uint32_t *pcbValue)); /** - * This method store NVRAM variable to storage + * Begins variable store sequence. + * + * @returns VBox status code. + * @param pInterance Pointer to this interface structure. + * @param cVariables The number of variables. */ - DECLR3CALLBACKMEMBER(int, pfnStoreNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, const char *pcszVariableName, size_t cbVariableName, uint8_t *pu8Value, size_t cbValue)); + DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqBegin,(PPDMINVRAMCONNECTOR pInterface, uint32_t cVariables)); /** - * This method load NVRAM variable to storage + * Puts the next variable in the store sequence. + * + * @returns VBox status code. + * @param idxVariable The variable index. This will start at 0 and advance + * up to @a cVariables - 1. + * @param pVendorUuid The vendor UUID of the variable. + * @param pszName The variable name buffer. + * @param pcchName On input this hold the name buffer size (including + * the space for the terminator char). On successful + * return it holds the strlen() value for @a pszName. + * @param fAttributes The value attributes. + * @param pbValue The value buffer. + * @param pcbValue On input the size of the value buffer, on output the + * actual number of bytes returned. */ - DECLR3CALLBACKMEMBER(int, pfnLoadNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, char *pcszVariableName, size_t *pcbVariableName, uint8_t *pu8Value, size_t *pcbValue)); - -} PDMINVRAM; + DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqPut,(PPDMINVRAMCONNECTOR pInterface, int idxVariable, + PCRTUUID pVendorUuid, const char *pszName, size_t cchName, + uint32_t fAttributes, uint8_t const *pbValue, size_t cbValue)); + /** + * Ends a variable store sequence. + * + * @returns VBox status code, @a rc on success. + * @param pInterance Pointer to this interface structure. + * @param rc The VBox status code for the whole store operation. + */ + DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqEnd,(PPDMINVRAMCONNECTOR pInterface, int rc)); -#define PDMINVRAM_IID "11226408-CB4C-4369-9218-1EE0092FB9F8" +} PDMINVRAMCONNECTOR; +/** PDMINVRAMCONNECTOR interface ID. */ +#define PDMINVRAMCONNECTOR_IID "057bc5c9-8022-43a8-9a41-0b106f97a89f" /** @} */ RT_C_DECLS_END - #endif - diff --git a/include/VBox/vmm/pdmqueue.h b/include/VBox/vmm/pdmqueue.h index 3445c85a..4edf16c3 100644 --- a/include/VBox/vmm/pdmqueue.h +++ b/include/VBox/vmm/pdmqueue.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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; @@ -65,6 +65,9 @@ typedef struct PDMQUEUEITEMCORE * If false the item will not be removed and the flushing will stop. * @param pDevIns The device instance. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks The device critical section will NOT be entered before calling the + * callback. No locks will be held, but for now it's safe to assume + * that only one EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEDEV(PPDMDEVINS pDevIns, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEDEV(). */ @@ -77,6 +80,8 @@ typedef FNPDMQUEUEDEV *PFNPDMQUEUEDEV; * If false the item will not be removed and the flushing will stop. * @param pDevIns The USB device instance. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEUSB(PPDMUSBINS pUsbIns, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEUSB(). */ @@ -89,6 +94,8 @@ typedef FNPDMQUEUEUSB *PFNPDMQUEUEUSB; * If false the item will not be removed and the flushing will stop. * @param pDrvIns The driver instance. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEDRV(PPDMDRVINS pDrvIns, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEDRV(). */ @@ -101,6 +108,8 @@ typedef FNPDMQUEUEDRV *PFNPDMQUEUEDRV; * If false the item will not be removed and the flushing will stop. * @param pVM The VM handle. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEINT(PVM pVM, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEINT(). */ @@ -113,6 +122,8 @@ typedef FNPDMQUEUEINT *PFNPDMQUEUEINT; * If false the item will not be removed and the flushing will stop. * @param pvUser User argument. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEEXT(void *pvUser, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEEXT(). */ diff --git a/include/VBox/vmm/pdmusb.h b/include/VBox/vmm/pdmusb.h index ae3f5cfb..6abe2a14 100644 --- a/include/VBox/vmm/pdmusb.h +++ b/include/VBox/vmm/pdmusb.h @@ -3,7 +3,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; @@ -113,6 +113,11 @@ typedef PDMUSBDESCCACHE *PPDMUSBDESCCACHE; typedef const PDMUSBDESCCACHE *PCPDMUSBDESCCACHE; +/** PDM Device Flags. + * @{ */ +/** A high-speed capable USB 2.0 device (also required to support full-speed). */ +#define PDM_USBREG_HIGHSPEED_CAPABLE RT_BIT(0) +/** @} */ /** PDM USB Device Registration Structure, * @@ -164,7 +169,7 @@ typedef struct PDMUSBREG * Most VM resources are freed by the VM. This callback is provided so that any non-VM * resources can be freed correctly. * - * This method will be called regardless of the pfnConstruc result to avoid + * This method will be called regardless of the pfnConstruct result to avoid * complicated failure paths. * * @param pUsbIns The USB device instance data. @@ -672,6 +677,38 @@ typedef struct PDMUSBHLP */ DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMUSBINS pUsbIns)); + /** + * Gets the reason for the most recent VM suspend. + * + * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no + * suspend has been made or if the pUsbIns is invalid. + * @param pUsbIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMUSBINS pUsbIns)); + + /** + * Gets the reason for the most recent VM resume. + * + * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no + * resume has been made or if the pUsbIns is invalid. + * @param pUsbIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMUSBINS pUsbIns)); + + /** @name Space reserved for minor interface changes. + * @{ */ + DECLR3CALLBACKMEMBER(void, pfnReserved0,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved1,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved2,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved3,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved4,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved5,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved6,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved7,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved8,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved9,(PPDMUSBINS pUsbIns)); + /** @} */ + /** Just a safety precaution. */ uint32_t u32TheEnd; } PDMUSBHLP; @@ -681,7 +718,7 @@ typedef PDMUSBHLP *PPDMUSBHLP; typedef const PDMUSBHLP *PCPDMUSBHLP; /** Current USBHLP version number. */ -#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 2, 0) +#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 3, 0) #endif /* IN_RING3 */ @@ -732,9 +769,12 @@ typedef struct PDMUSBINS uint32_t fTracing; /** The tracing ID of this device. */ uint32_t idTracing; + /** The USB version of the hub this device is attached to. Used to + * determine whether the device communicates at high-speed or full-/low-speed. */ + uint32_t iUsbHubVersion; /** Padding to make achInstanceData aligned at 32 byte boundary. */ - uint32_t au32Padding[HC_ARCH_BITS == 32 ? 3 : 4]; + uint32_t au32Padding[HC_ARCH_BITS == 32 ? 2 : 3]; /** Device instance data. The size of this area is defined * in the PDMUSBREG::cbInstanceData field. */ @@ -991,10 +1031,11 @@ typedef struct PDMUSBREGCB */ typedef DECLCALLBACK(int) FNPDMVBOXUSBREGISTER(PCPDMUSBREGCB pCallbacks, uint32_t u32Version); -VMMR3DECL(int) PDMR3USBCreateProxyDevice(PVM pVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend, +VMMR3DECL(int) PDMR3UsbCreateEmulatedDevice(PUVM pUVM, const char *pszDeviceName, PCFGMNODE pDeviceNode, PCRTUUID pUuid); +VMMR3DECL(int) PDMR3UsbCreateProxyDevice(PUVM pUVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend, uint32_t iUsbVersion, uint32_t fMaskedIfs); -VMMR3DECL(int) PDMR3USBDetachDevice(PVM pVM, PCRTUUID pUuid); -VMMR3DECL(bool) PDMR3USBHasHub(PVM pVM); +VMMR3DECL(int) PDMR3UsbDetachDevice(PUVM pUVM, PCRTUUID pUuid); +VMMR3DECL(bool) PDMR3UsbHasHub(PUVM pUVM); /** @} */ diff --git a/include/VBox/vmm/pdmwebcaminfs.h b/include/VBox/vmm/pdmwebcaminfs.h new file mode 100644 index 00000000..40b01614 --- /dev/null +++ b/include/VBox/vmm/pdmwebcaminfs.h @@ -0,0 +1,133 @@ +/* $Id: pdmwebcaminfs.h $ */ + +/** @file + * webcaminfs - interfaces between dev and driver. + */ + +/* + * Copyright (C) 2011-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 ___VBox_vmm_pdmwebcaminfs_h +#define ___VBox_vmm_pdmwebcaminfs_h + + +typedef struct PDMIWEBCAM_DEVICEDESC PDMIWEBCAM_DEVICEDESC; +typedef struct PDMIWEBCAM_CTRLHDR PDMIWEBCAM_CTRLHDR; +typedef struct PDMIWEBCAM_FRAMEHDR PDMIWEBCAM_FRAMEHDR; + + +#define PDMIWEBCAMDOWN_IID "0d29b9a1-f4cd-4719-a564-38d5634ba9f8" +typedef struct PDMIWEBCAMDOWN *PPDMIWEBCAMDOWN; +typedef struct PDMIWEBCAMDOWN +{ + /* + * The PDM device is ready to get webcam notifications. + * + * @param pInterface Pointer to the interface. + * @param fReady Whether the device is ready. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamDownReady, (PPDMIWEBCAMDOWN pInterface, + bool fReady)); + + /* + * Send a control request to the webcam. + * Async response will be returned by pfnWebcamUpControl callback. + * + * @param pInterface Pointer to the interface. + * @param pvUser The callers context. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pCtrl The control data. + * @param cbCtrl The size of the control data. + */ + DECLR3CALLBACKMEMBER(int, pfnWebcamDownControl, (PPDMIWEBCAMDOWN pInterface, + void *pvUser, + uint64_t u64DeviceId, + const PDMIWEBCAM_CTRLHDR *pCtrl, + uint32_t cbCtrl)); +} PDMIWEBCAMDOWN; + + +#define PDMIWEBCAMUP_IID "6ac03e3c-f56c-4a35-80af-c13ce47a9dd7" +typedef struct PDMIWEBCAMUP *PPDMIWEBCAMUP; +typedef struct PDMIWEBCAMUP +{ + /* + * A webcam is available. + * + * @param pInterface Pointer to the interface. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pDeviceDesc The device description. + * @param cbDeviceDesc The size of the device description. + * @param u32Version The remote video input protocol version. + * @param fu32Capabilities The remote video input protocol capabilities. + */ + DECLR3CALLBACKMEMBER(int, pfnWebcamUpAttached,(PPDMIWEBCAMUP pInterface, + uint64_t u64DeviceId, + const PDMIWEBCAM_DEVICEDESC *pDeviceDesc, + uint32_t cbDeviceDesc, + uint32_t u32Version, + uint32_t fu32Capabilities)); + + /* + * The webcam is not available anymore. + * + * @param pInterface Pointer to the interface. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamUpDetached,(PPDMIWEBCAMUP pInterface, + uint64_t u64DeviceId)); + + /* + * There is a control response or a control change for the webcam. + * + * @param pInterface Pointer to the interface. + * @param fResponse True if this is a response for a previous pfnWebcamDownControl call. + * @param pvUser The pvUser parameter of the pfnWebcamDownControl call. Undefined if fResponse == false. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pCtrl The control data. + * @param cbCtrl The size of the control data. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamUpControl,(PPDMIWEBCAMUP pInterface, + bool fResponse, + void *pvUser, + uint64_t u64DeviceId, + const PDMIWEBCAM_CTRLHDR *pCtrl, + uint32_t cbCtrl)); + + /* + * A new frame. + * + * @param pInterface Pointer to the interface. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pHeader Payload header. + * @param cbHeader Size of the payload header. + * @param pvFrame Frame (image) data. + * @param cbFrame Size of the image data. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamUpFrame,(PPDMIWEBCAMUP pInterface, + uint64_t u64DeviceId, + PDMIWEBCAM_FRAMEHDR *pHeader, + uint32_t cbHeader, + const void *pvFrame, + uint32_t cbFrame)); +} PDMIWEBCAMUP; + +#endif diff --git a/include/VBox/vmm/pgm.h b/include/VBox/vmm/pgm.h index 5d8b5f0d..7e397b2a 100644 --- a/include/VBox/vmm/pgm.h +++ b/include/VBox/vmm/pgm.h @@ -3,7 +3,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; @@ -333,13 +333,14 @@ VMMDECL(bool) PGMGstIsPagePresent(PVMCPU pVCpu, RTGCPTR GCPtr); VMMDECL(int) PGMGstSetPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags); VMMDECL(int) PGMGstModifyPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask); VMM_INT_DECL(int) PGMGstGetPaePdpes(PVMCPU pVCpu, PX86PDPE paPdpes); -VMM_INT_DECL(int) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes); +VMM_INT_DECL(void) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes); VMMDECL(int) PGMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCPtrPage); VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal); VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal); VMMDECL(int) PGMUpdateCR3(PVMCPU pVCpu, uint64_t cr3); VMMDECL(int) PGMChangeMode(PVMCPU pVCpu, uint64_t cr0, uint64_t cr4, uint64_t efer); +VMMDECL(void) PGMCr0WpEnabled(PVMCPU pVCpu); VMMDECL(PGMMODE) PGMGetGuestMode(PVMCPU pVCpu); VMMDECL(PGMMODE) PGMGetShadowMode(PVMCPU pVCpu); VMMDECL(PGMMODE) PGMGetHostMode(PVM pVM); @@ -383,7 +384,9 @@ VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, size_t cb); VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb, bool fRaiseTrap); VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, bool fRaiseTrap); -VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock); +VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock); +VMM_INT_DECL(int) PGMPhysIemQueryAccess(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers); + #ifdef VBOX_STRICT VMMDECL(unsigned) PGMAssertHandlerAndFlagsInSync(PVM pVM); VMMDECL(unsigned) PGMAssertNoMappingConflicts(PVM pVM); @@ -455,8 +458,9 @@ VMMR3DECL(int) PGMR3InitDynMap(PVM pVM); VMMR3DECL(int) PGMR3InitFinalize(PVM pVM); VMMR3_INT_DECL(int) PGMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); VMMR3DECL(void) PGMR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(void) PGMR3ResetUnpluggedCpu(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(void) PGMR3Reset(PVM pVM); +VMMR3DECL(void) PGMR3ResetCpu(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(void) PGMR3Reset(PVM pVM); +VMMR3_INT_DECL(void) PGMR3MemSetup(PVM pVM, bool fReset); VMMR3DECL(int) PGMR3Term(PVM pVM); VMMR3DECL(int) PGMR3LockCall(PVM pVM); VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode); @@ -468,8 +472,8 @@ VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pf VMMR3DECL(uint32_t) PGMR3PhysGetRamRangeCount(PVM pVM); VMMR3DECL(int) PGMR3PhysGetRange(PVM pVM, uint32_t iRange, PRTGCPHYS pGCPhysStart, PRTGCPHYS pGCPhysLast, const char **ppszDesc, bool *pfIsMmio); -VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem); -VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PVM pVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem); +VMMR3DECL(int) PGMR3QueryMemoryStats(PUVM pUVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem); +VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PUVM pUVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem); VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3, @@ -507,12 +511,13 @@ VMMDECL(void) PGMR3PhysSetA20(PVMCPU pVCpu, bool fEnable); VMMR3DECL(int) PGMR3MapPT(PVM pVM, RTGCPTR GCPtr, uint32_t cb, uint32_t fFlags, PFNPGMRELOCATE pfnRelocate, void *pvUser, const char *pszDesc); VMMR3DECL(int) PGMR3UnmapPT(PVM pVM, RTGCPTR GCPtr); VMMR3DECL(int) PGMR3FinalizeMappings(PVM pVM); -VMMR3DECL(int) PGMR3MappingsDisable(PVM pVM); VMMR3DECL(int) PGMR3MappingsSize(PVM pVM, uint32_t *pcb); VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb); VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM); VMMR3DECL(bool) PGMR3MappingsNeedReFixing(PVM pVM); +#if defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) VMMR3DECL(int) PGMR3MapIntermediate(PVM pVM, RTUINTPTR Addr, RTHCPHYS HCPhys, unsigned cbPages); +#endif VMMR3DECL(int) PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb); VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, @@ -552,15 +557,15 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys); VMMR3DECL(int) PGMR3CheckIntegrity(PVM pVM); -VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys); -VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys); -VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys); -VMMR3DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); -VMMR3DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); -VMMR3DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); -VMMR3DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); -VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit); -VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit); +VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys); +VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys); +VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PUVM pUVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys); +VMMR3_INT_DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); +VMMR3_INT_DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); +VMMR3_INT_DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); +VMMR3_INT_DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); +VMMR3_INT_DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit); +VMMR3_INT_DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit); VMMR3_INT_DECL(int) PGMR3DumpHierarchyShw(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); VMMR3_INT_DECL(int) PGMR3DumpHierarchyGst(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); diff --git a/include/VBox/vmm/rem.h b/include/VBox/vmm/rem.h index 79a18810..bda6e29a 100644 --- a/include/VBox/vmm/rem.h +++ b/include/VBox/vmm/rem.h @@ -3,7 +3,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/include/VBox/vmm/selm.h b/include/VBox/vmm/selm.h index 763d0acf..7503e734 100644 --- a/include/VBox/vmm/selm.h +++ b/include/VBox/vmm/selm.h @@ -41,7 +41,6 @@ RT_C_DECLS_BEGIN VMMDECL(RTSEL) SELMGetTrap8Selector(PVM pVM); VMMDECL(void) SELMSetTrap8EIP(PVM pVM, uint32_t u32EIP); VMMDECL(int) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, PRTGCPTR32 pEsp); -VMMDECL(RTGCPTR) SELMGetGuestTSS(PVM pVM); VMMDECL(RTSEL) SELMGetHyperCS(PVM pVM); VMMDECL(RTSEL) SELMGetHyperCS64(PVM pVM); VMMDECL(RTSEL) SELMGetHyperDS(PVM pVM); @@ -94,11 +93,12 @@ VMMR3DECL(int) SELMR3InitFinalize(PVM pVM); VMMR3DECL(void) SELMR3Relocate(PVM pVM); VMMR3DECL(int) SELMR3Term(PVM pVM); VMMR3DECL(void) SELMR3Reset(PVM pVM); +# ifdef VBOX_WITH_RAW_MODE VMMR3DECL(VBOXSTRICTRC) SELMR3UpdateFromCPUM(PVM pVM, PVMCPU pVCpu); VMMR3DECL(int) SELMR3SyncTSS(PVM pVM, PVMCPU pVCpu); +# endif VMMR3DECL(int) SELMR3GetSelectorInfo(PVM pVM, PVMCPU pVCpu, RTSEL Sel, PDBGFSELINFO pSelInfo); VMMR3DECL(int) SELMR3GetShadowSelectorInfo(PVM pVM, RTSEL Sel, PDBGFSELINFO pSelInfo); -VMMR3DECL(void) SELMR3DisableMonitoring(PVM pVM); VMMR3DECL(void) SELMR3DumpDescriptor(X86DESC Desc, RTSEL Sel, const char *pszMsg); VMMR3DECL(void) SELMR3DumpHyperGDT(PVM pVM); VMMR3DECL(void) SELMR3DumpHyperLDT(PVM pVM); @@ -106,6 +106,10 @@ VMMR3DECL(void) SELMR3DumpGuestGDT(PVM pVM); VMMR3DECL(void) SELMR3DumpGuestLDT(PVM pVM); VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM); VMMR3DECL(int) SELMR3DebugCheck(PVM pVM); +# ifdef VBOX_WITH_SAFE_STR +VMMR3DECL(bool) SELMR3CheckShadowTR(PVM pVM); +# endif + /** @def SELMR3_DEBUG_CHECK * Invokes SELMR3DebugCheck in stricts builds. */ # ifdef VBOX_STRICT diff --git a/include/VBox/vmm/ssm.h b/include/VBox/vmm/ssm.h index 427e0796..8218930f 100644 --- a/include/VBox/vmm/ssm.h +++ b/include/VBox/vmm/ssm.h @@ -3,7 +3,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; @@ -377,7 +377,11 @@ typedef struct SSMFIELD #define SSMSTRUCT_FLAGS_DONT_IGNORE RT_BIT_32(2) /** Saved using SSMR3PutMem, don't be too strict. */ #define SSMSTRUCT_FLAGS_SAVED_AS_MEM RT_BIT_32(3) -/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. */ +/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. + * @remarks This type is normally only used up to the first changes to the + * structures take place in order to make sure the conversion from + * SSMR3PutMem to field descriptors went smoothly. Replace with + * SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED when changing the structure. */ #define SSMSTRUCT_FLAGS_MEM_BAND_AID ( SSMSTRUCT_FLAGS_DONT_IGNORE | SSMSTRUCT_FLAGS_FULL_STRUCT \ | SSMSTRUCT_FLAGS_NO_MARKERS | SSMSTRUCT_FLAGS_SAVED_AS_MEM) /** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host @@ -399,6 +403,7 @@ typedef struct SSMFIELD * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. * @thread Any. */ typedef DECLCALLBACK(int) FNSSMDEVLIVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); @@ -415,6 +420,7 @@ typedef FNSSMDEVLIVEPREP *PFNSSMDEVLIVEPREP; * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. * @param uPass The pass. + * @remarks The caller enters the device critical section prior to the call. * @thread Any. */ typedef DECLCALLBACK(int) FNSSMDEVLIVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass); @@ -437,6 +443,7 @@ typedef FNSSMDEVLIVEEXEC *PFNSSMDEVLIVEEXEC; * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. * @param uPass The data pass. + * @remarks The caller enters the device critical section prior to the call. * @thread Any. */ typedef DECLCALLBACK(int) FNSSMDEVLIVEVOTE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass); @@ -449,6 +456,7 @@ typedef FNSSMDEVLIVEVOTE *PFNSSMDEVLIVEVOTE; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVSAVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVSAVEPREP() function. */ @@ -460,6 +468,7 @@ typedef FNSSMDEVSAVEPREP *PFNSSMDEVSAVEPREP; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVSAVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVSAVEEXEC() function. */ @@ -471,6 +480,7 @@ typedef FNSSMDEVSAVEEXEC *PFNSSMDEVSAVEEXEC; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVSAVEDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVSAVEDONE() function. */ @@ -482,6 +492,7 @@ typedef FNSSMDEVSAVEDONE *PFNSSMDEVSAVEDONE; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVLOADPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVLOADPREP() function. */ @@ -496,6 +507,7 @@ typedef FNSSMDEVLOADPREP *PFNSSMDEVLOADPREP; * @param uVersion Data layout version. * @param uPass The pass. This is always SSM_PASS_FINAL for units * that doesn't specify a pfnSaveLive callback. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVLOADEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass); /** Pointer to a FNSSMDEVLOADEXEC() function. */ @@ -507,6 +519,7 @@ typedef FNSSMDEVLOADEXEC *PFNSSMDEVLOADEXEC; * @returns VBox load code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVLOADDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVLOADDONE() function. */ @@ -1131,22 +1144,28 @@ typedef struct SSMSTRMOPS VMMR3_INT_DECL(void) SSMR3Term(PVM pVM); -VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore, - PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, - PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, - PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone); -VMMR3DECL(int) SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote, - PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone, - PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone); -VMMR3DECL(int) SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote, - PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone, - PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone); -VMMR3DECL(int) SSMR3RegisterExternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote, - PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone, - PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser); +VMMR3_INT_DECL(int) +SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, + size_t cbGuess, const char *pszBefore, + PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, + PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, + PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone); +VMMR3_INT_DECL(int) +SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote, + PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone, + PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone); +VMMR3DECL(int) +SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote, + PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone, + PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone); +VMMR3DECL(int) +SSMR3RegisterExternal(PUVM pUVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote, + PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone, + PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser); +VMMR3DECL(int) SSMR3RegisterStub(PVM pVM, const char *pszName, uint32_t uInstance); VMMR3_INT_DECL(int) SSMR3DeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance); VMMR3_INT_DECL(int) SSMR3DeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance); VMMR3DECL(int) SSMR3DeregisterInternal(PVM pVM, const char *pszName); @@ -1176,7 +1195,7 @@ VMMR3DECL(uint32_t) SSMR3HandleVersion(PSSMHANDLE pSSM); VMMR3DECL(const char *) SSMR3HandleHostOSAndArch(PSSMHANDLE pSSM); VMMR3_INT_DECL(int) SSMR3HandleSetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr); VMMR3DECL(void) SSMR3HandleReportLivePercent(PSSMHANDLE pSSM, unsigned uPercent); -VMMR3DECL(int) SSMR3Cancel(PVM pVM); +VMMR3DECL(int) SSMR3Cancel(PUVM pUVM); /** Save operations. diff --git a/include/VBox/vmm/stam.h b/include/VBox/vmm/stam.h index c25c606f..e7f2c556 100644 --- a/include/VBox/vmm/stam.h +++ b/include/VBox/vmm/stam.h @@ -3,7 +3,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; @@ -1200,38 +1200,17 @@ VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY e VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint, const char *pszDesc, const char *pszName, va_list args); -VMMR3DECL(int) STAMR3DeregisterU(PUVM pUVM, void *pvSample); -VMMR3DECL(int) STAMR3Deregister(PVM pVM, void *pvSample); - -/** @def STAM_REL_DEREG - * Deregisters a statistics sample if statistics are enabled. - * - * @param pVM VM Handle. - * @param pvSample Pointer to the sample. - */ -#define STAM_REL_DEREG(pVM, pvSample) \ - STAM_REL_STATS({ int rcStam = STAMR3Deregister(pVM, pvSample); AssertRC(rcStam); }) -/** @def STAM_DEREG - * Deregisters a statistics sample if statistics are enabled. - * - * @param pVM VM Handle. - * @param pvSample Pointer to the sample. - */ -#define STAM_DEREG(pVM, pvSample) \ - STAM_STATS({ STAM_REL_DEREG(pVM, pvSample); }) - -VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3Reset(PVM pVM, const char *pszPat); -VMMR3DECL(int) STAMR3SnapshotU(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); -VMMR3DECL(int) STAMR3Snapshot(PVM pVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); -VMMR3DECL(int) STAMR3SnapshotFreeU(PUVM pUVM, char *pszSnapshot); -VMMR3DECL(int) STAMR3SnapshotFree(PVM pVM, char *pszSnapshot); -VMMR3DECL(int) STAMR3DumpU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3Dump(PVM pVM, const char *pszPat); -VMMR3DECL(int) STAMR3DumpToReleaseLogU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3DumpToReleaseLog(PVM pVM, const char *pszPat); -VMMR3DECL(int) STAMR3PrintU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3Print(PVM pVM, const char *pszPat); +VMMR3DECL(int) STAMR3Deregister(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...); +VMMR3DECL(int) STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va); +VMMR3DECL(int) STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample); + +VMMR3DECL(int) STAMR3Reset(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3Snapshot(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); +VMMR3DECL(int) STAMR3SnapshotFree(PUVM pUVM, char *pszSnapshot); +VMMR3DECL(int) STAMR3Dump(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3DumpToReleaseLog(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3Print(PUVM pUVM, const char *pszPat); /** * Callback function for STAMR3Enum(). @@ -1251,8 +1230,7 @@ typedef DECLCALLBACK(int) FNSTAMR3ENUM(const char *pszName, STAMTYPE enmType, vo /** Pointer to a FNSTAMR3ENUM(). */ typedef FNSTAMR3ENUM *PFNSTAMR3ENUM; -VMMR3DECL(int) STAMR3EnumU(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); -VMMR3DECL(int) STAMR3Enum(PVM pVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); +VMMR3DECL(int) STAMR3Enum(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit); /** @} */ diff --git a/include/VBox/vmm/tm.h b/include/VBox/vmm/tm.h index be328b1c..8f857a4c 100644 --- a/include/VBox/vmm/tm.h +++ b/include/VBox/vmm/tm.h @@ -3,7 +3,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; @@ -87,9 +87,9 @@ VMM_INT_DECL(void) TMNotifyEndOfHalt(PVMCPU pVCpu); #ifdef IN_RING3 VMMR3DECL(int) TMR3NotifySuspend(PVM pVM, PVMCPU pVCpu); VMMR3DECL(int) TMR3NotifyResume(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(int) TMR3SetWarpDrive(PVM pVM, uint32_t u32Percent); +VMMR3DECL(int) TMR3SetWarpDrive(PUVM pUVM, uint32_t u32Percent); +VMMR3DECL(uint32_t) TMR3GetWarpDrive(PUVM pUVM); #endif -VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM); VMM_INT_DECL(uint32_t) TMCalcHostTimerFrequency(PVM pVM, PVMCPU pVCpu); #ifdef IN_RING3 VMMR3DECL(int) TMR3GetCpuLoadTimes(PVM pVM, VMCPUID idCpu, uint64_t *pcNsTotal, uint64_t *pcNsExecuting, diff --git a/include/VBox/vmm/trpm.h b/include/VBox/vmm/trpm.h index 0cdfc153..7dc436c6 100644 --- a/include/VBox/vmm/trpm.h +++ b/include/VBox/vmm/trpm.h @@ -3,7 +3,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; @@ -68,17 +68,20 @@ typedef TRPMEVENT const *PCTRPMEVENT; */ #define TRPM_INVALID_HANDLER 0 -VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType); +VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT penmType); VMMDECL(uint8_t) TRPMGetTrapNo(PVMCPU pVCpu); VMMDECL(RTGCUINT) TRPMGetErrorCode(PVMCPU pVCpu); VMMDECL(RTGCUINTPTR) TRPMGetFaultAddress(PVMCPU pVCpu); +VMMDECL(uint8_t) TRPMGetInstrLength(PVMCPU pVCpu); VMMDECL(int) TRPMResetTrap(PVMCPU pVCpu); VMMDECL(int) TRPMAssertTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType); +VMMDECL(int) TRPMAssertXcptPF(PVMCPU pVCpu, RTGCUINTPTR uCR2, RTGCUINT uErrorCode); VMMDECL(void) TRPMSetErrorCode(PVMCPU pVCpu, RTGCUINT uErrorCode); VMMDECL(void) TRPMSetFaultAddress(PVMCPU pVCpu, RTGCUINTPTR uCR2); +VMMDECL(void) TRPMSetInstrLength(PVMCPU pVCpu, uint8_t cbInstr); VMMDECL(bool) TRPMIsSoftwareInterrupt(PVMCPU pVCpu); VMMDECL(bool) TRPMHasTrap(PVMCPU pVCpu); -VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2); +VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2, uint8_t *pcbInstr); VMMDECL(void) TRPMSaveTrap(PVMCPU pVCpu); VMMDECL(void) TRPMRestoreTrap(PVMCPU pVCpu); VMMDECL(int) TRPMForwardTrap(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t cbInstr, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap); @@ -96,16 +99,17 @@ VMMR3DECL(int) TRPMR3Init(PVM pVM); VMMR3DECL(void) TRPMR3Relocate(PVM pVM, RTGCINTPTR offDelta); VMMR3DECL(void) TRPMR3ResetCpu(PVMCPU pVCpu); VMMR3DECL(void) TRPMR3Reset(PVM pVM); -VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3DECL(int) TRPMR3Term(PVM pVM); -VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap); -VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler); -VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap); -VMMR3DECL(void) TRPMR3DisableMonitoring(PVM pVM); +VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent); +# ifdef VBOX_WITH_RAW_MODE +VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3DECL(int) TRPMR3SyncIDT(PVM pVM, PVMCPU pVCpu); VMMR3DECL(bool) TRPMR3IsGateHandler(PVM pVM, RTRCPTR GCPtr); VMMR3DECL(uint32_t) TRPMR3QueryGateByHandler(PVM pVM, RTRCPTR GCPtr); -VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent); +VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap); +VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler); +VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap); +# endif /** @} */ #endif diff --git a/include/VBox/vmm/uvm.h b/include/VBox/vmm/uvm.h index 10b8e49b..37087752 100644 --- a/include/VBox/vmm/uvm.h +++ b/include/VBox/vmm/uvm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-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; @@ -55,6 +55,16 @@ typedef struct UVMCPU #endif uint8_t padding[512]; } vm; + + /** The DBGF data. */ + union + { +#ifdef ___DBGFInternal_h + struct DBGFUSERPERVMCPU s; +#endif + uint8_t padding[64]; + } dbgf; + } UVMCPU; AssertCompileMemberAlignment(UVMCPU, vm, 32); @@ -114,7 +124,7 @@ typedef struct UVM #ifdef ___PDMInternal_h struct PDMUSERPERVM s; #endif - uint8_t padding[128]; + uint8_t padding[256]; } pdm; /** The STAM data. */ @@ -123,9 +133,18 @@ typedef struct UVM #ifdef ___STAMInternal_h struct STAMUSERPERVM s; #endif - uint8_t padding[6624]; + uint8_t padding[6880]; } stam; + /** The DBGF data. */ + union + { +#ifdef ___DBGFInternal_h + struct DBGFUSERPERVM s; +#endif + uint8_t padding[256]; + } dbgf; + /** Per virtual CPU data. */ UVMCPU aCpus[1]; } UVM; diff --git a/include/VBox/vmm/vm.h b/include/VBox/vmm/vm.h index ef713127..bebb9836 100644 --- a/include/VBox/vmm/vm.h +++ b/include/VBox/vmm/vm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -68,7 +68,9 @@ typedef enum VMCPUSTATE /** CPU started. */ VMCPUSTATE_STARTED, - /** Executing guest code and can be poked. */ + /** CPU started in HM context. */ + VMCPUSTATE_STARTED_HM, + /** Executing guest code and can be poked (RC or STI bits of HM). */ VMCPUSTATE_STARTED_EXEC, /** Executing guest code in the recompiler. */ VMCPUSTATE_STARTED_EXEC_REM, @@ -84,7 +86,9 @@ typedef enum VMCPUSTATE /** - * Per virtual CPU data. + * The cross context virtual CPU structure. + * + * Run 'kmk run-struct-tests' (from src/VBox/VMM if you like) after updating! */ typedef struct VMCPU { @@ -110,7 +114,7 @@ typedef struct VMCPU /** The native R0 thread handle. (different from the R3 handle!) */ RTNATIVETHREAD hNativeThreadR0; /* 48 / 32 */ /** Which host CPU ID is this EMT running on. - * Only valid when in RC or HWACCMR0 with scheduling disabled. */ + * Only valid when in RC or HMR0 with scheduling disabled. */ RTCPUID volatile idHostCpu; /* 56 / 36 */ /** Trace groups enable flags. */ @@ -138,14 +142,14 @@ typedef struct VMCPU uint8_t padding[3584]; /* multiple of 64 */ } cpum; - /** HWACCM part. */ + /** HM part. */ union { -#ifdef ___HWACCMInternal_h - struct HWACCMCPU s; +#ifdef ___HMInternal_h + struct HMCPU s; #endif - uint8_t padding[5376]; /* multiple of 64 */ - } hwaccm; + uint8_t padding[5568]; /* multiple of 64 */ + } hm; /** EM part. */ union @@ -189,7 +193,7 @@ typedef struct VMCPU #ifdef ___VMMInternal_h struct VMMCPU s; #endif - uint8_t padding[640]; /* multiple of 64 */ + uint8_t padding[704]; /* multiple of 64 */ } vmm; /** PDM part. */ @@ -198,7 +202,7 @@ typedef struct VMCPU #ifdef ___PDMInternal_h struct PDMCPU s; #endif - uint8_t padding[128]; /* multiple of 64 */ + uint8_t padding[256]; /* multiple of 64 */ } pdm; /** IOM part. */ @@ -221,7 +225,7 @@ typedef struct VMCPU } dbgf; /** Align the following members on page boundary. */ - uint8_t abAlignment2[1024 - 320 - 128]; + uint8_t abAlignment2[192]; /** PGM part. */ union @@ -271,6 +275,16 @@ typedef struct VMCPU /** The name of the Ring 0 Context VMM Core module. */ #define VMMR0_MAIN_MODULE_NAME "VMMR0.r0" +/** + * Wrapper macro for avoiding too much \#ifdef VBOX_WITH_RAW_MODE. + */ +#ifdef VBOX_WITH_RAW_MODE +# define VM_WHEN_RAW_MODE(a_WithExpr, a_WithoutExpr) a_WithExpr +#else +# define VM_WHEN_RAW_MODE(a_WithExpr, a_WithoutExpr) a_WithoutExpr +#endif + + /** VM Forced Action Flags. * * Use the VM_FF_SET() and VM_FF_CLEAR() macros to change the force @@ -347,6 +361,12 @@ typedef struct VMCPU /** This action forces the VM to service pending requests from other * thread or requests which must be executed in another context. */ #define VMCPU_FF_REQUEST RT_BIT_32(9) +/** This action forces the VM to service any pending updates to CR3 (used only + * by HM). */ +#define VMCPU_FF_HM_UPDATE_CR3 RT_BIT_32(12) +/** This action forces the VM to service any pending updates to PAE PDPEs (used + * only by HM). */ +#define VMCPU_FF_HM_UPDATE_PAE_PDPES RT_BIT_32(13) /** This action forces the VM to resync the page tables before going * back to execute guest code. (GLOBAL FLUSH) */ #define VMCPU_FF_PGM_SYNC_CR3 RT_BIT_32(16) @@ -354,29 +374,33 @@ typedef struct VMCPU * (NON-GLOBAL FLUSH) */ #define VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL RT_BIT_32(17) /** Check for pending TLB shootdown actions. - * Consumer: HWACCM - * @todo rename to VMCPU_FF_HWACCM_TLB_SHOOTDOWN */ + * Consumer: HM + * @todo rename to VMCPU_FF_HM_TLB_SHOOTDOWN */ #define VMCPU_FF_TLB_SHOOTDOWN RT_BIT_32(18) /** Check for pending TLB flush action. - * Consumer: HWACCM - * @todo rename to VMCPU_FF_HWACCM_TLB_FLUSH */ + * Consumer: HM + * @todo rename to VMCPU_FF_HM_TLB_FLUSH */ #define VMCPU_FF_TLB_FLUSH RT_BIT_32(VMCPU_FF_TLB_FLUSH_BIT) /** The bit number for VMCPU_FF_TLB_FLUSH. */ #define VMCPU_FF_TLB_FLUSH_BIT 19 +#ifdef VBOX_WITH_RAW_MODE /** Check the interrupt and trap gates */ -#define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20) +# define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20) /** Check Guest's TSS ring 0 stack */ -#define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21) +# define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21) /** Check Guest's GDT table */ -#define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22) +# define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22) /** Check Guest's LDT table */ -#define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23) +# define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23) +#endif /* VBOX_WITH_RAW_MODE */ /** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */ #define VMCPU_FF_INHIBIT_INTERRUPTS RT_BIT_32(24) +#ifdef VBOX_WITH_RAW_MODE /** CSAM needs to scan the page that's being executed */ -#define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26) +# define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26) /** CSAM needs to do some homework. */ -#define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27) +# define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27) +#endif /* VBOX_WITH_RAW_MODE */ /** Force return to Ring-3. */ #define VMCPU_FF_TO_R3 RT_BIT_32(28) @@ -389,45 +413,67 @@ typedef struct VMCPU #define VM_FF_EXTERNAL_HALTED_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST \ | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_EMT_RENDEZVOUS) /** Externally forced VMCPU actions. Used to quit the idle/wait loop. */ -#define VMCPU_FF_EXTERNAL_HALTED_MASK (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_TIMER) +#define VMCPU_FF_EXTERNAL_HALTED_MASK ( VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST \ + | VMCPU_FF_TIMER) /** High priority VM pre-execution actions. */ #define VM_FF_HIGH_PRIORITY_PRE_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_TM_VIRTUAL_SYNC \ - | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) + | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY \ + | VM_FF_EMT_RENDEZVOUS) /** High priority VMCPU pre-execution actions. */ -#define VMCPU_FF_HIGH_PRIORITY_PRE_MASK ( VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 \ - | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ - | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS) +#define VMCPU_FF_HIGH_PRIORITY_PRE_MASK ( VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC \ + | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL \ + | VMCPU_FF_INHIBIT_INTERRUPTS \ + | VM_WHEN_RAW_MODE( VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ + | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT, 0 ) ) /** High priority VM pre raw-mode execution mask. */ #define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY) /** High priority VMCPU pre raw-mode execution mask. */ -#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ - | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS) +#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL \ + | VMCPU_FF_INHIBIT_INTERRUPTS \ + | VM_WHEN_RAW_MODE( VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ + | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT, 0) ) /** High priority post-execution actions. */ #define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PGM_NO_MEMORY) /** High priority post-execution actions. */ -#define VMCPU_FF_HIGH_PRIORITY_POST_MASK (VMCPU_FF_PDM_CRITSECT|VMCPU_FF_CSAM_PENDING_ACTION) +#define VMCPU_FF_HIGH_PRIORITY_POST_MASK ( VMCPU_FF_PDM_CRITSECT | VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_PENDING_ACTION, 0) \ + | VMCPU_FF_HM_UPDATE_CR3 | VMCPU_FF_HM_UPDATE_PAE_PDPES) /** Normal priority VM post-execution actions. */ #define VM_FF_NORMAL_PRIORITY_POST_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_RESET \ | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) /** Normal priority VMCPU post-execution actions. */ -#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK (VMCPU_FF_CSAM_SCAN_PAGE) +#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_SCAN_PAGE, 0) /** Normal priority VM actions. */ -#define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY | VM_FF_EMT_RENDEZVOUS) +#define VM_FF_NORMAL_PRIORITY_MASK ( VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY \ + | VM_FF_EMT_RENDEZVOUS) /** Normal priority VMCPU actions. */ #define VMCPU_FF_NORMAL_PRIORITY_MASK (VMCPU_FF_REQUEST) /** Flags to clear before resuming guest execution. */ #define VMCPU_FF_RESUME_GUEST_MASK (VMCPU_FF_TO_R3) -/** VM Flags that cause the HWACCM loops to go back to ring-3. */ -#define VM_FF_HWACCM_TO_R3_MASK (VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS) -/** VMCPU Flags that cause the HWACCM loops to go back to ring-3. */ -#define VMCPU_FF_HWACCM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT) +/** VM Flags that cause the HM loops to go back to ring-3. */ +#define VM_FF_HM_TO_R3_MASK ( VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY \ + | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS) +/** VMCPU Flags that cause the HM loops to go back to ring-3. */ +#define VMCPU_FF_HM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT) + +/** High priority ring-0 VM pre HM-mode execution mask. */ +#define VM_FF_HP_R0_PRE_HM_MASK (VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA) +/** High priority ring-0 VMCPU pre HM-mode execution mask. */ +#define VMCPU_FF_HP_R0_PRE_HM_MASK ( VMCPU_FF_HM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 \ + | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST) +/** High priority ring-0 VM pre HM-mode execution mask, single stepping. */ +#define VM_FF_HP_R0_PRE_HM_STEP_MASK (VM_FF_HP_R0_PRE_HM_MASK & ~( VM_FF_TM_VIRTUAL_SYNC | VM_FF_PDM_QUEUES \ + | VM_FF_EMT_RENDEZVOUS | VM_FF_REQUEST \ + | VM_FF_PDM_DMA) ) +/** High priority ring-0 VMCPU pre HM-mode execution mask, single stepping. */ +#define VMCPU_FF_HP_R0_PRE_HM_STEP_MASK (VMCPU_FF_HP_R0_PRE_HM_MASK & ~( VMCPU_FF_TO_R3 | VMCPU_FF_TIMER \ + | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_REQUEST) ) /** All the forced VM flags. */ #define VM_FF_ALL_MASK (~0U) @@ -439,14 +485,15 @@ typedef struct VMCPU #define VM_FF_ALL_REM_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK) | VM_FF_PGM_NO_MEMORY) /** All the forced VMCPU flags except those related to raw-mode and hardware * assisted execution. */ -#define VMCPU_FF_ALL_REM_MASK (~(VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN)) - +#define VMCPU_FF_ALL_REM_MASK (~( VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_PDM_CRITSECT \ + | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN \ + | VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_PENDING_ACTION, 0) )) /** @} */ /** @def VM_FF_SET * Sets a force action flag. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlag The flag to set. */ #if 1 @@ -461,15 +508,15 @@ typedef struct VMCPU /** @def VMCPU_FF_SET * Sets a force action flag for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlag The flag to set. */ -#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag)) +#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag)) /** @def VM_FF_CLEAR * Clears a force action flag. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlag The flag to clear. */ #if 1 @@ -484,80 +531,68 @@ typedef struct VMCPU /** @def VMCPU_FF_CLEAR * Clears a force action flag for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlag The flag to clear. */ -#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag)) +#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag)) -/** @def VM_FF_ISSET +/** @def VM_FF_IS_SET * Checks if a force action flag is set. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlag The flag to check. */ #define VM_FF_IS_SET(pVM, fFlag) (((pVM)->fGlobalForcedActions & (fFlag)) == (fFlag)) -/** @deprecated */ -#define VM_FF_ISSET(pVM, fFlag) VM_FF_IS_SET(pVM, fFlag) -/** @def VMCPU_FF_ISSET +/** @def VMCPU_FF_IS_SET * Checks if a force action flag is set for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlag The flag to check. */ #define VMCPU_FF_IS_SET(pVCpu, fFlag) (((pVCpu)->fLocalForcedActions & (fFlag)) == (fFlag)) -/** @deprecated */ -#define VMCPU_FF_ISSET(pVCpu, fFlag) VMCPU_FF_IS_SET(pVCpu, fFlag) -/** @def VM_FF_ISPENDING +/** @def VM_FF_IS_PENDING * Checks if one or more force action in the specified set is pending. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlags The flags to check for. */ -#define VM_FF_IS_PENDING(pVM, fFlags) ((pVM)->fGlobalForcedActions & (fFlags)) -/** @deprecated */ -#define VM_FF_ISPENDING(pVM, fFlags) VM_FF_IS_PENDING(pVM, fFlags) +#define VM_FF_IS_PENDING(pVM, fFlags) RT_BOOL((pVM)->fGlobalForcedActions & (fFlags)) /** @def VM_FF_TESTANDCLEAR * Checks if one (!) force action in the specified set is pending and clears it atomically * * @returns true if the bit was set. * @returns false if the bit was clear. - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param iBit Bit position to check and clear */ #define VM_FF_TEST_AND_CLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT)) -/** @deprecated */ -#define VM_FF_TESTANDCLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT)) /** @def VMCPU_FF_TESTANDCLEAR * Checks if one (!) force action in the specified set is pending and clears it atomically * * @returns true if the bit was set. * @returns false if the bit was clear. - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param iBit Bit position to check and clear */ #define VMCPU_FF_TEST_AND_CLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT)) -/** @deprecated */ -#define VMCPU_FF_TESTANDCLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT)) -/** @def VMCPU_FF_ISPENDING +/** @def VMCPU_FF_IS_PENDING * Checks if one or more force action in the specified set is pending for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlags The flags to check for. */ -#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) ((pVCpu)->fLocalForcedActions & (fFlags)) -/** @deprecated */ -#define VMCPU_FF_ISPENDING(pVCpu, fFlags) VMCPU_FF_IS_PENDING(pVCpu, fFlags) +#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) RT_BOOL((pVCpu)->fLocalForcedActions & (fFlags)) -/** @def VM_FF_ISPENDING +/** @def VM_FF_IS_PENDING_EXCEPT * Checks if one or more force action in the specified set is pending while one * or more other ones are not. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlags The flags to check for. * @param fExcpt The flags that should not be set. */ @@ -567,7 +602,7 @@ typedef struct VMCPU * Checks if one or more force action in the specified set is pending for the given * VCPU while one or more other ones are not. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlags The flags to check for. * @param fExcpt The flags that should not be set. */ @@ -615,7 +650,10 @@ typedef struct VMCPU #ifdef IN_RC # define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu)) #elif defined(IN_RING0) -# define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu)) +# define VMCPU_ASSERT_EMT(pVCpu) AssertMsg(VMCPU_IS_EMT(pVCpu), \ + ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%u\n", \ + RTThreadNativeSelf(), (pVCpu) ? (pVCpu)->hNativeThreadR0 : 0, \ + (pVCpu) ? (pVCpu)->idCpu : 0)) #else # define VMCPU_ASSERT_EMT(pVCpu) \ AssertMsg(VMCPU_IS_EMT(pVCpu), \ @@ -723,15 +761,21 @@ typedef struct VMCPU ("state %s, expected %s\n", VMGetStateName((pVM)->enmVMState), VMGetStateName(_enmState)), \ (rc)) +/** @def VM_IS_VALID_EXT + * Asserts a the VM handle is valid for external access, i.e. not being destroy + * or terminated. */ +#define VM_IS_VALID_EXT(pVM) \ + ( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \ + && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \ + || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \ + && VM_IS_EMT(pVM))) ) + /** @def VM_ASSERT_VALID_EXT_RETURN * Asserts a the VM handle is valid for external access, i.e. not being * destroy or terminated. */ #define VM_ASSERT_VALID_EXT_RETURN(pVM, rc) \ - AssertMsgReturn( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \ - && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \ - || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \ - && VM_IS_EMT(pVM))), \ + AssertMsgReturn(VM_IS_VALID_EXT(pVM), \ ("pVM=%p state %s\n", (pVM), RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \ ? VMGetStateName(pVM->enmVMState) : ""), \ (rc)) @@ -753,17 +797,17 @@ typedef struct VMCPU -/** This is the VM structure. +/** + * The cross context VM structure. * - * It contains (nearly?) all the VM data which have to be available in all - * contexts. Even if it contains all the data the idea is to use APIs not - * to modify all the members all around the place. Therefore we make use of - * unions to hide everything which isn't local to the current source module. - * This means we'll have to pay a little bit of attention when adding new - * members to structures in the unions and make sure to keep the padding sizes - * up to date. + * It contains all the VM data which have to be available in all contexts. + * Even if it contains all the data the idea is to use APIs not to modify all + * the members all around the place. Therefore we make use of unions to hide + * everything which isn't local to the current source module. This means we'll + * have to pay a little bit of attention when adding new members to structures + * in the unions and make sure to keep the padding sizes up to date. * - * Run tstVMStructSize after update! + * Run 'kmk run-struct-tests' (from src/VBox/VMM if you like) after updating! */ typedef struct VM { @@ -835,6 +879,8 @@ typedef struct VM bool fRecompileUser; /** Whether to recompile supervisor mode code or run it raw/hm. */ bool fRecompileSupervisor; + /** Whether raw mode supports ring-1 code or not. */ + bool fRawRing1Enabled; /** PATM enabled flag. * This is placed here for performance reasons. */ bool fPATMEnabled; @@ -842,19 +888,26 @@ typedef struct VM * This is placed here for performance reasons. */ bool fCSAMEnabled; /** Hardware VM support is available and enabled. + * Determined very early during init. * This is placed here for performance reasons. */ - bool fHWACCMEnabled; - /** Hardware VM support is required and non-optional. - * This is initialized together with the rest of the VM structure. */ - bool fHwVirtExtForced; - /** Set when this VM is the master FT node. */ + bool fHMEnabled; + /** For asserting on fHMEnable usage. */ + bool fHMEnabledFixed; + /** Hardware VM support requires a minimal raw-mode context. + * This is never set on 64-bit hosts, only 32-bit hosts requires it. */ + bool fHMNeedRawModeCtx; + /** Set when this VM is the master FT node. + * @todo This doesn't need to be here, FTM should store it in it's own + * structures instead. */ bool fFaultTolerantMaster; - /** Large page enabled flag. */ + /** Large page enabled flag. + * @todo This doesn't need to be here, PGM should store it in it's own + * structures instead. */ bool fUseLargePages; /** @} */ /** Alignment padding.. */ - uint32_t uPadding1; + uint8_t uPadding1[2]; /** @name Debugging * @{ */ @@ -929,14 +982,14 @@ typedef struct VM uint8_t padding[4096*2+6080]; /* multiple of 64 */ } pgm; - /** HWACCM part. */ + /** HM part. */ union { -#ifdef ___HWACCMInternal_h - struct HWACCM s; +#ifdef ___HMInternal_h + struct HM s; #endif - uint8_t padding[5376]; /* multiple of 64 */ - } hwaccm; + uint8_t padding[5440]; /* multiple of 64 */ + } hm; /** TRPM part. */ union @@ -980,7 +1033,7 @@ typedef struct VM #ifdef ___IOMInternal_h struct IOM s; #endif - uint8_t padding[832]; /* multiple of 64 */ + uint8_t padding[896]; /* multiple of 64 */ } iom; /** PATM part. */ @@ -1077,7 +1130,7 @@ typedef struct VM /** Padding for aligning the cpu array on a page boundary. */ - uint8_t abAlignment2[542]; + uint8_t abAlignment2[414]; /* ---- end small stuff ---- */ diff --git a/include/VBox/vmm/vm.mac b/include/VBox/vmm/vm.mac index 6d65b0c9..2a1be76b 100644 --- a/include/VBox/vmm/vm.mac +++ b/include/VBox/vmm/vm.mac @@ -3,7 +3,7 @@ ; ; -; Copyright (C) 2006-2012 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; @@ -58,14 +58,16 @@ struc VM .pfnVMMRCToHostAsmNoReturn resd 1 .fRecompileUser resb 1 .fRecompileSupervisor resb 1 + .fRawRing1Enabled resb 1 .fPATMEnabled resb 1 .fCSAMEnabled resb 1 - .fHWACCMEnabled resb 1 - .fHwVirtExtForced resb 1 + .fHMEnabled resb 1 + .fHMEnabledFixed resb 1 + .fHMNeedRawModeCtx resb 1 .fFaultTolerantMaster resb 1 .fUseLargePages resb 1 - .uPadding1 resd 1 + .uPadding1 resb 2 .hTraceBufRC RTRCPTR_RES 1 .hTraceBufR3 RTR3PTR_RES 1 @@ -132,13 +134,13 @@ struc VMCPU alignb 64 .cpum resb 3584 - .hwaccm resb 5376 + .hm resb 5568 .em resb 1472 .iem resb 3072 .trpm resb 128 .tm resb 384 - .vmm resb 640 - .pdm resb 128 + .vmm resb 704 + .pdm resb 256 .iom resb 512 .dbgf resb 64 alignb 4096 diff --git a/include/VBox/vmm/vmapi.h b/include/VBox/vmm/vmapi.h index b15fc7f6..d19ac645 100644 --- a/include/VBox/vmm/vmapi.h +++ b/include/VBox/vmm/vmapi.h @@ -3,7 +3,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; @@ -92,20 +92,20 @@ RT_C_DECLS_BEGIN /** * VM error callback function. * - * @param pVM The VM handle. Can be NULL if an error occurred before - * successfully creating a VM. + * @param pUVM The user mode VM handle. Can be NULL if an error + * occurred before successfully creating a VM. * @param pvUser The user argument. * @param rc VBox status code. * @param RT_SRC_POS_DECL The source position arguments. See RT_SRC_POS and RT_SRC_POS_ARGS. * @param pszFormat Error message format string. * @param args Error message arguments. */ -typedef DECLCALLBACK(void) FNVMATERROR(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args); +typedef DECLCALLBACK(void) FNVMATERROR(PUVM pUVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args); /** Pointer to a VM error callback. */ typedef FNVMATERROR *PFNVMATERROR; -VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...); -VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args); +VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...); +VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args); /** @def VM_SET_ERROR * Macro for setting a simple VM error message. @@ -122,20 +122,35 @@ VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat */ #define VM_SET_ERROR(pVM, rc, pszMessage) (VMSetError(pVM, rc, RT_SRC_POS, pszMessage)) +/** @def VM_SET_ERROR + * Macro for setting a simple VM error message. + * Don't use '%' in the message! + * + * @returns rc. Meaning you can do: + * @code + * return VM_SET_ERROR(pVM, VERR_OF_YOUR_CHOICE, "descriptive message"); + * @endcode + * @param pVM VM handle. + * @param rc VBox status code. + * @param pszMessage Error message string. + * @thread Any + */ +#define VM_SET_ERROR_U(a_pUVM, a_rc, a_pszMessage) (VMR3SetError(a_pUVM, a_rc, RT_SRC_POS, a_pszMessage)) + /** * VM runtime error callback function. * * See VMSetRuntimeError for the detailed description of parameters. * - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param pvUser The user argument. * @param fFlags The error flags. * @param pszErrorId Error ID string. * @param pszFormat Error message format string. * @param va Error message arguments. */ -typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PVM pVM, void *pvUser, uint32_t fFlags, const char *pszErrorId, +typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PUVM pUVM, void *pvUser, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va); /** Pointer to a VM runtime error callback. */ typedef FNVMATRUNTIMEERROR *PFNVMATRUNTIMEERROR; @@ -163,17 +178,17 @@ VMMDECL(int) VMSetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId /** @} */ /** - * VM state callback function. + * VM state change callback function. * * You are not allowed to call any function which changes the VM state from a * state callback, except VMR3Destroy(). * - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param enmState The new state. * @param enmOldState The old state. * @param pvUser The user argument. */ -typedef DECLCALLBACK(void) FNVMATSTATE(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser); +typedef DECLCALLBACK(void) FNVMATSTATE(PUVM pUVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser); /** Pointer to a VM state callback. */ typedef FNVMATSTATE *PFNVMATSTATE; @@ -309,45 +324,102 @@ typedef enum VMINITCOMPLETED /** The ring-0 init is completed. */ VMINITCOMPLETED_RING0, /** The hardware accelerated virtualization init is completed. - * Used to make decisision depending on whether HWACCMIsEnabled(). */ - VMINITCOMPLETED_HWACCM, - /** The GC init is completed. */ - VMINITCOMPLETED_GC + * Used to make decisision depending on HM* bits being completely + * initialized. */ + VMINITCOMPLETED_HM, + /** The RC init is completed. */ + VMINITCOMPLETED_RC } VMINITCOMPLETED; -VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs, - PFNVMATERROR pfnVMAtError, void *pvUserVM, - PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM, - PVM *ppVM); -VMMR3DECL(int) VMR3PowerOn(PVM pVM); -VMMR3DECL(int) VMR3Suspend(PVM pVM); -VMMR3DECL(int) VMR3Resume(PVM pVM); -VMMR3DECL(int) VMR3Reset(PVM pVM); +/** Reason for VM resume. */ +typedef enum VMRESUMEREASON +{ + VMRESUMEREASON_INVALID = 0, + /** User decided to do so. */ + VMRESUMEREASON_USER, + /** VM reconfiguration (like changing DVD). */ + VMRESUMEREASON_RECONFIG, + /** The host resumed. */ + VMRESUMEREASON_HOST_RESUME, + /** Restored state. */ + VMRESUMEREASON_STATE_RESTORED, + /** Snapshot / saved state. */ + VMRESUMEREASON_STATE_SAVED, + /** Teleported to a new box / instance. */ + VMRESUMEREASON_TELEPORTED, + /** Teleportation failed. */ + VMRESUMEREASON_TELEPORT_FAILED, + /** FTM temporarily suspended the VM. */ + VMRESUMEREASON_FTM_SYNC, + /** End of valid reasons. */ + VMRESUMEREASON_END, + /** Blow the type up to 32-bits. */ + VMRESUMEREASON_32BIT_HACK = 0x7fffffff +} VMRESUMEREASON; + +/** Reason for VM suspend. */ +typedef enum VMSUSPENDREASON +{ + VMSUSPENDREASON_INVALID = 0, + /** User decided to do so. */ + VMSUSPENDREASON_USER, + /** VM reconfiguration (like changing DVD). */ + VMSUSPENDREASON_RECONFIG, + /** The VM is suspending itself. */ + VMSUSPENDREASON_VM, + /** The Vm is suspending because of a runtime error. */ + VMSUSPENDREASON_RUNTIME_ERROR, + /** The host was suspended. */ + VMSUSPENDREASON_HOST_SUSPEND, + /** The host is running low on battery power. */ + VMSUSPENDREASON_HOST_BATTERY_LOW, + /** FTM is temporarily suspending the VM. */ + VMSUSPENDREASON_FTM_SYNC, + /** End of valid reasons. */ + VMSUSPENDREASON_END, + /** Blow the type up to 32-bits. */ + VMSUSPENDREASON_32BIT_HACK = 0x7fffffff +} VMSUSPENDREASON; + /** * Progress callback. + * * This will report the completion percentage of an operation. * * @returns VINF_SUCCESS. * @returns Error code to cancel the operation with. - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param uPercent Completion percentage (0-100). * @param pvUser User specified argument. */ -typedef DECLCALLBACK(int) FNVMPROGRESS(PVM pVM, unsigned uPercent, void *pvUser); +typedef DECLCALLBACK(int) FNVMPROGRESS(PUVM pUVM, unsigned uPercent, void *pvUser); /** Pointer to a FNVMPROGRESS function. */ typedef FNVMPROGRESS *PFNVMPROGRESS; -VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended); -VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended); -VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); -VMMR3DECL(int) VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, - PFNVMPROGRESS pfnProgress, void *pvProgressUser); -VMMR3DECL(int) VMR3PowerOff(PVM pVM); -VMMR3DECL(int) VMR3Destroy(PVM pVM); -VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(PVM) VMR3EnumVMs(PVM pVMPrev); + +VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs, + PFNVMATERROR pfnVMAtError, void *pvUserVM, + PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM, + PVM *ppVM, PUVM *ppUVM); +VMMR3DECL(int) VMR3PowerOn(PUVM pUVM); +VMMR3DECL(int) VMR3Suspend(PUVM pUVM, VMSUSPENDREASON enmReason); +VMMR3DECL(VMSUSPENDREASON) VMR3GetSuspendReason(PUVM); +VMMR3DECL(int) VMR3Resume(PUVM pUVM, VMRESUMEREASON enmReason); +VMMR3DECL(VMRESUMEREASON) VMR3GetResumeReason(PUVM); +VMMR3DECL(int) VMR3Reset(PUVM pUVM); +VMMR3DECL(int) VMR3Save(PUVM pUVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended); +VMMR3_INT_DECL(int) VMR3SaveFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, bool fSkipStateChanges); +VMMR3DECL(int) VMR3Teleport(PUVM pUVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended); +VMMR3DECL(int) VMR3LoadFromFile(PUVM pUVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); +VMMR3DECL(int) VMR3LoadFromStream(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, + PFNVMPROGRESS pfnProgress, void *pvProgressUser); +VMMR3_INT_DECL(int) VMR3LoadFromStreamFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser); + +VMMR3DECL(int) VMR3PowerOff(PUVM pUVM); +VMMR3DECL(int) VMR3Destroy(PUVM pUVM); +VMMR3_INT_DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta); VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM); VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM); @@ -358,48 +430,38 @@ VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid); VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM); VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM); VMMR3DECL(const char *) VMR3GetStateName(VMSTATE enmState); +VMMR3DECL(int) VMR3AtStateRegister(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser); +VMMR3DECL(int) VMR3AtStateDeregister(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser); +VMMR3_INT_DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM); +VMMR3DECL(int) VMR3AtErrorRegister(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser); +VMMR3DECL(int) VMR3AtErrorDeregister(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser); +VMMR3DECL(int) VMR3SetError(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...); +VMMR3DECL(int) VMR3SetErrorV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va); +VMMR3_INT_DECL(void) VMR3SetErrorWorker(PVM pVM); +VMMR3_INT_DECL(uint32_t) VMR3GetErrorCount(PUVM pUVM); +VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); +VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); +VMMR3_INT_DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM); +VMMR3_INT_DECL(uint32_t) VMR3GetRuntimeErrorCount(PUVM pUVM); + +VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args); +VMMR3_INT_DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallNoWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3_INT_DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallVoidWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqPriorityCallWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqPriorityCallVoidWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqAlloc(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu); +VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq); +VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies); +VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies); +VMMR3_INT_DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly); -/** - * VM destruction callback. - * @param pVM The VM which is about to be destroyed. - * @param pvUser The user parameter specified at registration. - */ -typedef DECLCALLBACK(void) FNVMATDTOR(PVM pVM, void *pvUser); -/** Pointer to a VM destruction callback. */ -typedef FNVMATDTOR *PFNVMATDTOR; - -VMMR3DECL(int) VMR3AtDtorRegister(PFNVMATDTOR pfnAtDtor, void *pvUser); -VMMR3DECL(int) VMR3AtDtorDeregister(PFNVMATDTOR pfnAtDtor); -VMMR3DECL(int) VMR3AtStateRegister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser); -VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser); -VMMR3DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM); -VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser); -VMMR3DECL(int) VMR3AtErrorRegisterU(PUVM pVM, PFNVMATERROR pfnAtError, void *pvUser); -VMMR3DECL(int) VMR3AtErrorDeregister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser); -VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM); -VMMR3DECL(uint32_t) VMR3GetErrorCount(PVM pVM); -VMMR3DECL(uint32_t) VMR3GetErrorCountU(PUVM pUVM); -VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); -VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); -VMMR3DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM); -VMMR3DECL(uint32_t) VMR3GetRuntimeErrorCount(PVM pVM); -VMMR3DECL(int) VMR3ReqCall(PVM pVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args); -VMMR3DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqPriorityCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqAlloc(PVM pVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu); -VMMR3DECL(int) VMR3ReqAllocU(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu); -VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq); -VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies); -VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies); -VMMR3DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly); -VMMR3DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags); -VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags); /** @name Flags for VMR3NotifyCpuFFU and VMR3NotifyGlobalFFU. * @{ */ /** Whether we've done REM or not. */ @@ -407,20 +469,21 @@ VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags); /** Whether we should poke the CPU if it's executing guest code. */ #define VMNOTIFYFF_FLAGS_POKE RT_BIT_32(1) /** @} */ - -VMMR3DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts); -VMMR3DECL(int) VMR3WaitU(PUVMCPU pUVMCpu); +VMMR3_INT_DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags); +VMMR3_INT_DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags); +VMMR3_INT_DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts); +VMMR3_INT_DECL(int) VMR3WaitU(PUVMCPU pUVMCpu); VMMR3_INT_DECL(int) VMR3AsyncPdmNotificationWaitU(PUVMCPU pUVCpu); VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM); -VMMR3DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM); -VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PVM pVM); -VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM); +VMMR3_INT_DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM); +VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PUVM pUVM); VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThread(PVM pVM); VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThreadU(PUVM pUVM); -VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage); -VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu); -VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu); -VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap); +VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PUVM pUVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage); +VMMR3DECL(int) VMR3HotUnplugCpu(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(int) VMR3HotPlugCpu(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(int) VMR3SetCpuExecutionCap(PUVM pUVM, uint32_t uCpuExecutionCap); +VMMR3DECL(int) VMR3SetPowerOffInsteadOfReset(PUVM pUVM, bool fPowerOffInsteadOfReset); /** @} */ #endif /* IN_RING3 */ diff --git a/include/VBox/vmm/vmm.h b/include/VBox/vmm/vmm.h index e3af0c29..bd3cee05 100644 --- a/include/VBox/vmm/vmm.h +++ b/include/VBox/vmm/vmm.h @@ -3,7 +3,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; @@ -31,6 +31,7 @@ #include #include #include +#include RT_C_DECLS_BEGIN @@ -63,6 +64,10 @@ typedef enum VMMSWITCHER VMMSWITCHER_AMD64_TO_PAE, /** Switcher for AMD64 host paging to AMD64 shadow paging. */ VMMSWITCHER_AMD64_TO_AMD64, + /** Stub switcher for 32-bit and PAE. */ + VMMSWITCHER_X86_STUB, + /** Stub switcher for AMD64. */ + VMMSWITCHER_AMD64_STUB, /** Used to make a count for array declarations and suchlike. */ VMMSWITCHER_MAX, /** The usual 32-bit paranoia. */ @@ -81,6 +86,10 @@ typedef enum VMMCALLRING3 VMMCALLRING3_PDM_LOCK, /** Acquire the critical section specified as argument. */ VMMCALLRING3_PDM_CRIT_SECT_ENTER, + /** Enter the R/W critical section (in argument) exclusively. */ + VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_EXCL, + /** Enter the R/W critical section (in argument) shared. */ + VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_SHARED, /** Acquire the PGM lock. */ VMMCALLRING3_PGM_LOCK, /** Grow the PGM shadow page pool. */ @@ -103,7 +112,8 @@ typedef enum VMMCALLRING3 VMMCALLRING3_VM_SET_RUNTIME_ERROR, /** Signal a ring 0 assertion. */ VMMCALLRING3_VM_R0_ASSERTION, - /** Ring switch to force preemption. */ + /** Ring switch to force preemption. This is also used by PDMCritSect to + * handle VERR_INTERRUPTED in kernel context. */ VMMCALLRING3_VM_R0_PREEMPT, /** Sync the FTM state with the standby node. */ VMMCALLRING3_FTM_SET_CHECKPOINT, @@ -112,17 +122,16 @@ typedef enum VMMCALLRING3 } VMMCALLRING3; /** - * VMMR3AtomicExecuteHandler callback function. + * VMMRZCallRing3 notification callback. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pvUser User specified argument - * - * @todo missing prefix. + * @param pVCpu Pointer to the VMCPU. + * @param enmOperation The operation causing the ring-3 jump. + * @param pvUser The user argument. */ -typedef DECLCALLBACK(int) FNATOMICHANDLER(PVM pVM, void *pvUser); -/** Pointer to a FNMMATOMICHANDLER(). */ -typedef FNATOMICHANDLER *PFNATOMICHANDLER; +typedef DECLCALLBACK(int) FNVMMR0CALLRING3NOTIFICATION(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser); +/** Pointer to a FNRTMPNOTIFICATION(). */ +typedef FNVMMR0CALLRING3NOTIFICATION *PFNVMMR0CALLRING3NOTIFICATION; /** * Rendezvous callback. @@ -213,6 +222,16 @@ typedef struct VMM2USERMETHODS */ DECLR3CALLBACKMEMBER(void, pfnNotifyPdmtTerm,(PCVMM2USERMETHODS pThis, PUVM pUVM)); + /** + * Notification callback that that a VM reset will be turned into a power off. + * + * @param pThis Pointer to the callback method table. + * @param pUVM The user mode VM handle. + * + * @remarks This is optional and shall be set to NULL if not wanted. + */ + DECLR3CALLBACKMEMBER(void, pfnNotifyResetTurnedIntoPowerOff,(PCVMM2USERMETHODS pThis, PUVM pUVM)); + /** Magic value (VMM2USERMETHODS_MAGIC) marking the end of the structure. */ uint32_t u32EndMagic; } VMM2USERMETHODS; @@ -220,28 +239,34 @@ typedef struct VMM2USERMETHODS /** Magic value of the VMM2USERMETHODS (Franz Kafka). */ #define VMM2USERMETHODS_MAGIC UINT32_C(0x18830703) /** The VMM2USERMETHODS structure version. */ -#define VMM2USERMETHODS_VERSION UINT32_C(0x00020000) +#define VMM2USERMETHODS_VERSION UINT32_C(0x00020001) -VMMDECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu); -VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM); -VMMDECL(PVMCPU) VMMGetCpu(PVM pVM); -VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM); -VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu); -VMMDECL(uint32_t) VMMGetSvnRev(void); -VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM); -VMMDECL(void) VMMTrashVolatileXMMRegs(void); - -/** @def VMMIsHwVirtExtForced - * Checks if forced to use the hardware assisted virtualization extensions. - * - * This is intended for making setup decisions where we can save resources when - * using hardware assisted virtualization. +/** + * Checks whether we've armed the ring-0 long jump machinery. * - * @returns true / false. - * @param pVM Pointer to the shared VM structure. + * @returns @c true / @c false + * @param pVCpu The caller's cross context virtual CPU structure. + * @thread EMT + * @sa VMMR0IsLongJumpArmed */ -#define VMMIsHwVirtExtForced(pVM) ((pVM)->fHwVirtExtForced) +#ifdef IN_RING0 +# define VMMIsLongJumpArmed(a_pVCpu) VMMR0IsLongJumpArmed(a_pVCpu) +#else +# define VMMIsLongJumpArmed(a_pVCpu) (false) +#endif + + +VMM_INT_DECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu); +VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM); +VMMDECL(PVMCPU) VMMGetCpu(PVM pVM); +VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM); +VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu); +VMMR3DECL(PVMCPU) VMMR3GetCpuByIdU(PUVM pVM, VMCPUID idCpu); +VMM_INT_DECL(uint32_t) VMMGetSvnRev(void); +VMM_INT_DECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM); +VMM_INT_DECL(bool) VMMIsInRing3Call(PVMCPU pVCpu); +VMM_INT_DECL(void) VMMTrashVolatileXMMRegs(void); #ifdef IN_RING3 @@ -251,23 +276,26 @@ VMMDECL(void) VMMTrashVolatileXMMRegs(void); */ VMMR3_INT_DECL(int) VMMR3Init(PVM pVM); VMMR3_INT_DECL(int) VMMR3InitR0(PVM pVM); +# ifdef VBOX_WITH_RAW_MODE VMMR3_INT_DECL(int) VMMR3InitRC(PVM pVM); +# endif VMMR3_INT_DECL(int) VMMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); VMMR3_INT_DECL(int) VMMR3Term(PVM pVM); VMMR3_INT_DECL(void) VMMR3Relocate(PVM pVM, RTGCINTPTR offDelta); VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM); VMMR3DECL(const char *) VMMR3GetRZAssertMsg1(PVM pVM); VMMR3DECL(const char *) VMMR3GetRZAssertMsg2(PVM pVM); -VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3_INT_DECL(int) VMMR3SelectSwitcher(PVM pVM, VMMSWITCHER enmSwitcher); -VMMR3_INT_DECL(int) VMMR3DisableSwitcher(PVM pVM); VMMR3_INT_DECL(RTR0PTR) VMMR3GetHostToGuestSwitcher(PVM pVM, VMMSWITCHER enmSwitcher); +VMMR3_INT_DECL(int) VMMR3HmRunGC(PVM pVM, PVMCPU pVCpu); +# ifdef VBOX_WITH_RAW_MODE VMMR3_INT_DECL(int) VMMR3RawRunGC(PVM pVM, PVMCPU pVCpu); -VMMR3_INT_DECL(int) VMMR3HwAccRunGC(PVM pVM, PVMCPU pVCpu); +VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3DECL(int) VMMR3CallRC(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, ...); VMMR3DECL(int) VMMR3CallRCV(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, va_list args); +# endif VMMR3DECL(int) VMMR3CallR0(PVM pVM, uint32_t uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr); -VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu); VMMR3DECL(void) VMMR3FatalDump(PVM pVM, PVMCPU pVCpu, int rcErr); VMMR3_INT_DECL(void) VMMR3YieldSuspend(PVM pVM); VMMR3_INT_DECL(void) VMMR3YieldStop(PVM pVM); @@ -320,7 +348,7 @@ typedef enum VMMR0OPERATION /** Run guest context. */ VMMR0_DO_RAW_RUN = SUP_VMMR0_DO_RAW_RUN, /** Run guest code using the available hardware acceleration technology. */ - VMMR0_DO_HWACC_RUN = SUP_VMMR0_DO_HWACC_RUN, + VMMR0_DO_HM_RUN = SUP_VMMR0_DO_HM_RUN, /** Official NOP that we use for profiling. */ VMMR0_DO_NOP = SUP_VMMR0_DO_NOP, /** Official slow iocl NOP that we use for profiling. */ @@ -352,9 +380,9 @@ typedef enum VMMR0OPERATION /** Call VMMR0 Per VM Termination. */ VMMR0_DO_VMMR0_TERM, /** Setup the hardware accelerated raw-mode session. */ - VMMR0_DO_HWACC_SETUP_VM, + VMMR0_DO_HM_SETUP_VM, /** Attempt to enable or disable hardware accelerated raw-mode. */ - VMMR0_DO_HWACC_ENABLE, + VMMR0_DO_HM_ENABLE, /** Calls function in the hypervisor. * The caller must setup the hypervisor context so the call will be performed. * The difference between VMMR0_DO_RUN_GC and this one is the handling of @@ -475,18 +503,30 @@ typedef struct GCFGMVALUEREQ */ typedef GCFGMVALUEREQ *PGCFGMVALUEREQ; -VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg); -VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation); -VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION); -VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM); - -#ifdef LOG_ENABLED -VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu); -VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu); -#else -#define VMMR0LogFlushDisable(pVCpu) do { } while(0) -#define VMMR0LogFlushEnable(pVCpu) do { } while(0) -#endif +#ifdef IN_RING0 +VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg); +VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation); +VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION); +VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM); +VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu); +VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPU pVCpu); +VMMR0DECL(int) VMMR0ThreadCtxHooksCreate(PVMCPU pVCpu); +VMMR0DECL(void) VMMR0ThreadCtxHooksRelease(PVMCPU pVCpu); +VMMR0DECL(bool) VMMR0ThreadCtxHooksAreCreated(PVMCPU pVCpu); +VMMR0DECL(int) VMMR0ThreadCtxHooksRegister(PVMCPU pVCpu, PFNRTTHREADCTXHOOK pfnHook); +VMMR0DECL(int) VMMR0ThreadCtxHooksDeregister(PVMCPU pVCpu); +VMMR0DECL(bool) VMMR0ThreadCtxHooksAreRegistered(PVMCPU pVCpu); + +# ifdef LOG_ENABLED +VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu); +VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu); +VMMR0DECL(bool) VMMR0IsLogFlushDisabled(PVMCPU pVCpu); +# else +# define VMMR0LogFlushDisable(pVCpu) do { } while(0) +# define VMMR0LogFlushEnable(pVCpu) do { } while(0) +# define VMMR0IsLogFlushDisabled(pVCpu) (true) +# endif /* LOG_ENABLED */ +#endif /* IN_RING0 */ /** @} */ @@ -512,6 +552,9 @@ VMMRZDECL(int) VMMRZCallRing3NoCpu(PVM pVM, VMMCALLRING3 enmOperation, uint VMMRZDECL(void) VMMRZCallRing3Disable(PVMCPU pVCpu); VMMRZDECL(void) VMMRZCallRing3Enable(PVMCPU pVCpu); VMMRZDECL(bool) VMMRZCallRing3IsEnabled(PVMCPU pVCpu); +VMMRZDECL(int) VMMRZCallRing3SetNotification(PVMCPU pVCpu, R0PTRTYPE(PFNVMMR0CALLRING3NOTIFICATION) pfnCallback, RTR0PTR pvUser); +VMMRZDECL(void) VMMRZCallRing3RemoveNotification(PVMCPU pVCpu); +VMMRZDECL(bool) VMMRZCallRing3IsNotificationSet(PVMCPU pVCpu); /** @} */ #endif diff --git a/include/VBox/vrdpusb.h b/include/VBox/vrdpusb.h index 92491500..69bdeb6b 100644 --- a/include/VBox/vrdpusb.h +++ b/include/VBox/vrdpusb.h @@ -3,7 +3,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/include/VBox/vscsi.h b/include/VBox/vscsi.h index 217ce885..f3544cb2 100644 --- a/include/VBox/vscsi.h +++ b/include/VBox/vscsi.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; @@ -120,6 +120,32 @@ typedef struct VSCSILUNIOCALLBACKS void *pvScsiLunUser, uint64_t *pcbSize)); + /** + * Retrieve the sector size of the underlying medium. + * + * @returns VBox status status code. + * @param hVScsiLun Virtual SCSI LUN handle. + * @param pvScsiLunUser Opaque user data which may + * be used to identify the medium. + * @param pcbSectorSize Where to store the sector size of the + * medium. + */ + DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumGetSectorSize, (VSCSILUN hVScsiLun, + void *pvScsiLunUser, + uint32_t *pcbSectorSize)); + + /** + * Set the lock state of the underlying medium. + * + * @returns VBox status status code. + * @param hVScsiLun Virtual SCSI LUN handle. + * @param pvScsiLunUser Opaque user data which may + * be used to identify the medium. + * @param fLocked New lock state (locked/unlocked). + */ + DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumSetLock, (VSCSILUN hVScsiLun, + void *pvScsiLunUser, + bool fLocked)); /** * Enqueue a read or write request from the medium. * @@ -269,6 +295,22 @@ VBOXDDU_DECL(int) VSCSILunCreate(PVSCSILUN phVScsiLun, VSCSILUNTYPE enmLunType, */ VBOXDDU_DECL(int) VSCSILunDestroy(VSCSILUN hVScsiLun); +/** + * Notify virtual SCSI LUN of medium being mounted. + * + * @returns VBox status code. + * @param hVScsiLun The virtual SCSI LUN handle to destroy. + */ +VBOXDDU_DECL(int) VSCSILunMountNotify(VSCSILUN hVScsiLun); + +/** + * Notify virtual SCSI LUN of medium being unmounted. + * + * @returns VBox status code. + * @param hVScsiLun The virtual SCSI LUN handle to destroy. + */ +VBOXDDU_DECL(int) VSCSILunUnmountNotify(VSCSILUN hVScsiLun); + /** * Notify a that a I/O request completed. * diff --git a/include/VBox/vusb.h b/include/VBox/vusb.h index 3a2d9b8f..c1aba4f0 100644 --- a/include/VBox/vusb.h +++ b/include/VBox/vusb.h @@ -3,7 +3,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; @@ -54,6 +54,7 @@ RT_C_DECLS_BEGIN #define VUSB_DT_DEVICE_QUALIFIER 0x06 #define VUSB_DT_OTHER_SPEED_CFG 0x07 #define VUSB_DT_INTERFACE_POWER 0x08 +#define VUSB_DT_INTERFACE_ASSOCIATION 0x0B /** @} */ /** @name USB Descriptor minimum sizes (from spec) @@ -161,6 +162,26 @@ typedef VUSBDESCCONFIG *PVUSBDESCCONFIG; typedef const VUSBDESCCONFIG *PCVUSBDESCCONFIG; +/** + * USB interface association descriptor (from USB ECN Interface Association Descriptors) + */ +typedef struct VUSBDESCIAD +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} VUSBDESCIAD; +/** Pointer to a USB interface association descriptor. */ +typedef VUSBDESCIAD *PVUSBDESCIAD; +/** Pointer to a readonly USB interface association descriptor. */ +typedef const VUSBDESCIAD *PCVUSBDESCIAD; + + /** * USB interface descriptor (from spec) */ @@ -256,6 +277,11 @@ typedef struct VUSBDESCINTERFACEEX /** Pointer to an array of the endpoints referenced by the interface. * Core.bNumEndpoints in size. */ const struct VUSBDESCENDPOINTEX *paEndpoints; + /** Interface association descriptor, which prepends a group of interfaces, + * starting with this interface. */ + PCVUSBDESCIAD pIAD; + /** Size of interface association descriptor. */ + uint16_t cbIAD; } VUSBDESCINTERFACEEX; /** Pointer to an prased USB interface descriptor. */ typedef VUSBDESCINTERFACEEX *PVUSBDESCINTERFACEEX; diff --git a/include/iprt/aiomgr.h b/include/iprt/aiomgr.h new file mode 100644 index 00000000..651d29ee --- /dev/null +++ b/include/iprt/aiomgr.h @@ -0,0 +1,155 @@ +/** @file + * IPRT - Async I/O manager. + */ + +/* + * 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 ___iprt_aiomgr_h +#define ___iprt_aiomgr_h + +#include +#include +#include + +/** + * Completion callback. + * + * @returns nothing. + * @param hAioMgrFile File handle the completed request was for. + * @param rcReq Status code of the completed request. + * @param pvUser Opaque user data given when the request was initiated. + */ +typedef DECLCALLBACK(void) FNRTAIOMGRREQCOMPLETE(RTAIOMGRFILE hAioMgrFile, int rcReq, void *pvUser); +/** Pointer to a completion callback. */ +typedef FNRTAIOMGRREQCOMPLETE *PFNRTAIOMGRREQCOMPLETE; + +RT_C_DECLS_BEGIN + +/** + * Create a new async I/O manager. + * + * @returns IPRT statuse code. + * @param phAioMgr Where to store the new async I/O manager handle on success. + * @param cReqsMax Maximum number of async I/O requests expected. + * Use UINT32_MAX to make it grow dynamically when required. + */ +RTDECL(int) RTAioMgrCreate(PRTAIOMGR phAioMgr, uint32_t cReqsMax); + +/** + * Retain a async I/O manager handle. + * + * @returns New reference count on success, UINT32_MAX on failure. + * @param hAioMgr The async I/O manager to retain. + */ +RTDECL(uint32_t) RTAioMgrRetain(RTAIOMGR hAioMgr); + +/** + * Releases a async I/O manager handle. + * + * @returns New reference count on success (0 if closed), UINT32_MAX on failure. + * @param hAioMgr The async I/O manager to release. + */ +RTDECL(uint32_t) RTAioMgrRelease(RTAIOMGR hAioMgr); + +/** + * Assign a given file handle to the given async I/O manager. + * + * @returns IPRT status code. + * @param hAioMgr Async I/O manager handle. + * @param hFile File handle to assign. + * @param pfnReqComplete Callback to execute whenever a request for the + * file completed. + * @param phAioMgrFile Where to store the newly created async I/O manager + * handle on success. + * @param pvUser Opaque user data for this file handle. + * + * @note This function increases the reference count of the given async I/O manager + * by 1. + */ +RTDECL(int) RTAioMgrFileCreate(RTAIOMGR hAioMgr, RTFILE hFile, PFNRTAIOMGRREQCOMPLETE pfnReqComplete, + void *pvUser, PRTAIOMGRFILE phAioMgrFile); + +/** + * Retain a async I/O manager file handle. + * + * @returns New reference count on success, UINT32_MAX on failure. + * @param hAioMgrFile The file handle to retain. + */ +RTDECL(uint32_t) RTAioMgrFileRetain(RTAIOMGRFILE hAioMgrFile); + +/** + * Releases a async I/O manager file handle. + * + * @returns New reference count on success (0 if closed), UINT32_MAX on failure. + * @param hAioMgrFile The file handle to release. + */ +RTDECL(uint32_t) RTAioMgrFileRelease(RTAIOMGRFILE hAioMgrFile); + +/** + * Return opaque user data passed on creation. + * + * @returns Opaque user data or NULL if the handle is invalid. + * @param hAioMgrFile The file handle. + */ +RTDECL(void *) RTAioMgrFileGetUser(RTAIOMGRFILE hAioMgrFile); + +/** + * Initiate a read request from the given file handle. + * + * @returns IPRT status code. + * @param hAioMgrFile The file handle to read from. + * @param off Start offset to read from. + * @param pSgBuf S/G buffer to read into. The buffer is advanced + * by the amount of data to read. + * @param cbRead Number of bytes to read. + * @param pvUser Opaque user data given in the completion callback. + */ +RTDECL(int) RTAioMgrFileRead(RTAIOMGRFILE hAioMgrFile, RTFOFF off, + PRTSGBUF pSgBuf, size_t cbRead, void *pvUser); + +/** + * Initiate a write request to the given file handle. + * + * @returns IPRT status code. + * @param hAioMgrFile The file handle to write to. + * @param off Start offset to write to. + * @param pSgBuf S/G buffer to read from. The buffer is advanced + * by the amount of data to write. + * @param cbWrite Number of bytes to write. + * @param pvUser Opaque user data given in the completion callback. + */ +RTDECL(int) RTAioMgrFileWrite(RTAIOMGRFILE hAioMgrFile, RTFOFF off, + PRTSGBUF pSgBuf, size_t cbWrite, void *pvUser); + +/** + * Initiates a flush request for the given file handle. + * + * @returns IPRT statuse code. + * @param hAioMgrFile The file handle to write to. + * @param pvUser Opaque user data given in the completion callback. + */ +RTDECL(int) RTAioMgrFileFlush(RTAIOMGRFILE hAioMgrFile, void *pvUser); + +RT_C_DECLS_END + +#endif + diff --git a/include/iprt/alloc.h b/include/iprt/alloc.h index e30b7f87..783c1898 100644 --- a/include/iprt/alloc.h +++ b/include/iprt/alloc.h @@ -3,7 +3,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/include/iprt/alloca.h b/include/iprt/alloca.h index 4aa00e6a..c47771cd 100644 --- a/include/iprt/alloca.h +++ b/include/iprt/alloca.h @@ -3,7 +3,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/include/iprt/asm-amd64-x86.h b/include/iprt/asm-amd64-x86.h index 22efb441..b0f0c5bc 100644 --- a/include/iprt/asm-amd64-x86.h +++ b/include/iprt/asm-amd64-x86.h @@ -3,7 +3,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; @@ -68,6 +68,10 @@ # pragma intrinsic(__readcr8) # pragma intrinsic(__writecr8) # endif +# if RT_INLINE_ASM_USES_INTRIN >= 15 +# pragma intrinsic(__readeflags) +# pragma intrinsic(__writeeflags) +# endif #endif @@ -349,11 +353,76 @@ DECLINLINE(RTSEL) ASMGetTR(void) #endif +/** + * Get the LDTR register. + * @returns LDTR. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(RTSEL) ASMGetLDTR(void); +#else +DECLINLINE(RTSEL) ASMGetLDTR(void) +{ + RTSEL SelLDTR; +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__("sldt %w0\n\t" : "=r" (SelLDTR)); +# else + __asm + { + sldt ax + mov [SelLDTR], ax + } +# endif + return SelLDTR; +} +#endif + + +/** + * Get the access rights for the segment selector. + * + * @returns The access rights on success or ~0U on failure. + * @param uSel The selector value. + * + * @remarks Using ~0U for failure is chosen because valid access rights always + * have bits 0:7 as 0 (on both Intel & AMD). + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(uint32_t) ASMGetSegAttr(uint32_t uSel); +#else +DECLINLINE(uint32_t) ASMGetSegAttr(uint32_t uSel) +{ + uint32_t uAttr; + /* LAR only accesses 16-bit of the source operand, but eax for the + destination operand is required for getting the full 32-bit access rights. */ +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__("lar %1, %%eax\n\t" + "jz done%=\n\t" + "movl $0xffffffff, %%eax\n\t" + "done%=:\n\t" + "movl %%eax, %0\n\t" + : "=r" (uAttr) + : "r" (uSel) + : "cc", "%eax"); +# else + __asm + { + lar eax, [uSel] + jz done + mov eax, 0ffffffffh + done: + mov [uAttr], eax + } +# endif + return uAttr; +} +#endif + + /** * Get the [RE]FLAGS register. * @returns [RE]FLAGS. */ -#if RT_INLINE_ASM_EXTERNAL +#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15 DECLASM(RTCCUINTREG) ASMGetFlags(void); #else DECLINLINE(RTCCUINTREG) ASMGetFlags(void) @@ -369,6 +438,8 @@ DECLINLINE(RTCCUINTREG) ASMGetFlags(void) "popl %0\n\t" : "=r" (uFlags)); # endif +# elif RT_INLINE_ASM_USES_INTRIN >= 15 + uFlags = __readeflags(); # else __asm { @@ -390,7 +461,7 @@ DECLINLINE(RTCCUINTREG) ASMGetFlags(void) * Set the [RE]FLAGS register. * @param uFlags The new [RE]FLAGS value. */ -#if RT_INLINE_ASM_EXTERNAL +#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15 DECLASM(void) ASMSetFlags(RTCCUINTREG uFlags); #else DECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags) @@ -405,6 +476,8 @@ DECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags) "popfl\n\t" : : "g" (uFlags)); # endif +# elif RT_INLINE_ASM_USES_INTRIN >= 15 + __writeeflags(uFlags); # else __asm { @@ -524,8 +597,8 @@ DECLINLINE(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pv /** - * Performs the cpuid instruction returning all registers. - * Some subfunctions of cpuid take ECX as additional parameter (currently known for EAX=4) + * Performs the CPUID instruction with EAX and ECX input returning ALL output + * registers. * * @param uOperator CPUID operation (eax). * @param uIdxECX ecx index @@ -535,7 +608,7 @@ DECLINLINE(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pv * @param pvEDX Where to store edx. * @remark We're using void pointers to ease the use of special bitfield structures and such. */ -#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN +#if RT_INLINE_ASM_EXTERNAL || RT_INLINE_ASM_USES_INTRIN DECLASM(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX); #else DECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX) @@ -568,8 +641,7 @@ DECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pv # elif RT_INLINE_ASM_USES_INTRIN int aInfo[4]; - /* ??? another intrinsic ??? */ - __cpuid(aInfo, uOperator); + __cpuidex(aInfo, uOperator, uIdxECX); *(uint32_t *)pvEAX = aInfo[0]; *(uint32_t *)pvEBX = aInfo[1]; *(uint32_t *)pvECX = aInfo[2]; @@ -601,6 +673,23 @@ DECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pv #endif +/** + * CPUID variant that initializes all 4 registers before the CPUID instruction. + * + * @returns The EAX result value. + * @param uOperator CPUID operation (eax). + * @param uInitEBX The value to assign EBX prior to the CPUID instruction. + * @param uInitECX The value to assign ECX prior to the CPUID instruction. + * @param uInitEDX The value to assign EDX prior to the CPUID instruction. + * @param pvEAX Where to store eax. Optional. + * @param pvEBX Where to store ebx. Optional. + * @param pvECX Where to store ecx. Optional. + * @param pvEDX Where to store edx. Optional. + */ +DECLASM(uint32_t) ASMCpuIdExSlow(uint32_t uOperator, uint32_t uInitEBX, uint32_t uInitECX, uint32_t uInitEDX, + void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX); + + /** * Performs the cpuid instruction returning ecx and edx. * @@ -979,7 +1068,7 @@ DECLINLINE(bool) ASMIsIntelCpu(void) /** - * Tests if it a authentic AMD CPU based on the ASMCpuId(0) output. + * Tests if it an authentic AMD CPU based on the ASMCpuId(0) output. * * @returns true/false. * @param uEBX EBX return from ASMCpuId(0) @@ -1008,6 +1097,71 @@ DECLINLINE(bool) ASMIsAmdCpu(void) } +/** + * Tests if it a centaur hauling VIA CPU based on the ASMCpuId(0) output. + * + * @returns true/false. + * @param uEBX EBX return from ASMCpuId(0). + * @param uECX ECX return from ASMCpuId(0). + * @param uEDX EDX return from ASMCpuId(0). + */ +DECLINLINE(bool) ASMIsViaCentaurCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX) +{ + return uEBX == UINT32_C(0x746e6543) + && uECX == UINT32_C(0x736c7561) + && uEDX == UINT32_C(0x48727561); +} + + +/** + * Tests if this is a centaur hauling VIA CPU. + * + * @returns true/false. + * @remarks ASSUMES that cpuid is supported by the CPU. + */ +DECLINLINE(bool) ASMIsViaCentaurCpu(void) +{ + uint32_t uEAX, uEBX, uECX, uEDX; + ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX); + return ASMIsAmdCpuEx(uEBX, uECX, uEDX); +} + + +/** + * Checks whether ASMCpuId_EAX(0x00000000) indicates a valid range. + * + * + * @returns true/false. + * @param uEAX The EAX value of CPUID leaf 0x00000000. + * + * @note This only succeeds if there are at least two leaves in the range. + * @remarks The upper range limit is just some half reasonable value we've + * picked out of thin air. + */ +DECLINLINE(bool) ASMIsValidStdRange(uint32_t uEAX) +{ + return uEAX >= UINT32_C(0x00000001) && uEAX <= UINT32_C(0x000fffff); +} + + +/** + * Checks whether ASMCpuId_EAX(0x80000000) indicates a valid range. + * + * This only succeeds if there are at least two leaves in the range. + * + * @returns true/false. + * @param uEAX The EAX value of CPUID leaf 0x80000000. + * + * @note This only succeeds if there are at least two leaves in the range. + * @remarks The upper range limit is just some half reasonable value we've + * picked out of thin air. + */ +DECLINLINE(bool) ASMIsValidExtRange(uint32_t uEAX) +{ + return uEAX >= UINT32_C(0x80000001) && uEAX <= UINT32_C(0x800fffff); +} + + /** * Extracts the CPU family from ASMCpuId(1) or ASMCpuId(0x80000001) * @@ -1611,6 +1765,82 @@ DECLINLINE(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val) #endif +/** + * Reads a machine specific register, extended version (for AMD). + * + * @returns Register content. + * @param uRegister Register to read. + * @param uXDI RDI/EDI value. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(uint64_t) ASMRdMsrEx(uint32_t uRegister, RTCCUINTREG uXDI); +#else +DECLINLINE(uint64_t) ASMRdMsrEx(uint32_t uRegister, RTCCUINTREG uXDI) +{ + RTUINT64U u; +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__("rdmsr\n\t" + : "=a" (u.s.Lo), + "=d" (u.s.Hi) + : "c" (uRegister), + "D" (uXDI)); + +# else + __asm + { + mov ecx, [uRegister] + xchg edi, [uXDI] + rdmsr + mov [u.s.Lo], eax + mov [u.s.Hi], edx + xchg edi, [uXDI] + } +# endif + + return u.u; +} +#endif + + +/** + * Writes a machine specific register, extended version (for AMD). + * + * @returns Register content. + * @param uRegister Register to write to. + * @param uXDI RDI/EDI value. + * @param u64Val Value to write. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(void) ASMWrMsrEx(uint32_t uRegister, RTCCUINTREG uXDI, uint64_t u64Val); +#else +DECLINLINE(void) ASMWrMsrEx(uint32_t uRegister, RTCCUINTREG uXDI, uint64_t u64Val) +{ + RTUINT64U u; + + u.u = u64Val; +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__("wrmsr\n\t" + ::"a" (u.s.Lo), + "d" (u.s.Hi), + "c" (uRegister), + "D" (uXDI)); + +# else + __asm + { + mov ecx, [uRegister] + xchg edi, [uXDI] + mov edx, [u.s.Hi] + mov eax, [u.s.Lo] + wrmsr + xchg edi, [uXDI] + } +# endif +} +#endif + + + /** * Reads low part of a machine specific register. * diff --git a/include/iprt/asm.h b/include/iprt/asm.h index abaef3a0..92db9484 100644 --- a/include/iprt/asm.h +++ b/include/iprt/asm.h @@ -3,7 +3,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; @@ -2992,6 +2992,8 @@ DECLINLINE(void) ASMAtomicOrS64(int64_t volatile *pi64, int64_t i64) { ASMAtomicOrU64((uint64_t volatile *)pi64, i64); } + + /** * Atomically And an unsigned 32-bit value, ordered. * @@ -3085,6 +3087,180 @@ DECLINLINE(void) ASMAtomicAndS64(int64_t volatile *pi64, int64_t i64) } +/** + * Atomically OR an unsigned 32-bit value, unordered but interrupt safe. + * + * @param pu32 Pointer to the pointer variable to OR u32 with. + * @param u32 The value to OR *pu32 with. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(void) ASMAtomicUoOrU32(uint32_t volatile *pu32, uint32_t u32); +#else +DECLINLINE(void) ASMAtomicUoOrU32(uint32_t volatile *pu32, uint32_t u32) +{ +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__("orl %1, %0\n\t" + : "=m" (*pu32) + : "ir" (u32), + "m" (*pu32)); +# else + __asm + { + mov eax, [u32] +# ifdef RT_ARCH_AMD64 + mov rdx, [pu32] + or [rdx], eax +# else + mov edx, [pu32] + or [edx], eax +# endif + } +# endif +} +#endif + + +/** + * Atomically OR a signed 32-bit value, unordered. + * + * @param pi32 Pointer to the pointer variable to OR u32 with. + * @param i32 The value to OR *pu32 with. + */ +DECLINLINE(void) ASMAtomicUoOrS32(int32_t volatile *pi32, int32_t i32) +{ + ASMAtomicUoOrU32((uint32_t volatile *)pi32, i32); +} + + +/** + * Atomically OR an unsigned 64-bit value, unordered. + * + * @param pu64 Pointer to the pointer variable to OR u64 with. + * @param u64 The value to OR *pu64 with. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(void) ASMAtomicUoOrU64(uint64_t volatile *pu64, uint64_t u64); +#else +DECLINLINE(void) ASMAtomicUoOrU64(uint64_t volatile *pu64, uint64_t u64) +{ +# if RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) + __asm__ __volatile__("orq %1, %q0\n\t" + : "=m" (*pu64) + : "r" (u64), + "m" (*pu64)); +# else + for (;;) + { + uint64_t u64Old = ASMAtomicUoReadU64(pu64); + uint64_t u64New = u64Old | u64; + if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old)) + break; + ASMNopPause(); + } +# endif +} +#endif + + +/** + * Atomically Or a signed 64-bit value, unordered. + * + * @param pi64 Pointer to the pointer variable to OR u64 with. + * @param i64 The value to OR *pu64 with. + */ +DECLINLINE(void) ASMAtomicUoOrS64(int64_t volatile *pi64, int64_t i64) +{ + ASMAtomicUoOrU64((uint64_t volatile *)pi64, i64); +} + + +/** + * Atomically And an unsigned 32-bit value, unordered. + * + * @param pu32 Pointer to the pointer variable to AND u32 with. + * @param u32 The value to AND *pu32 with. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(void) ASMAtomicUoAndU32(uint32_t volatile *pu32, uint32_t u32); +#else +DECLINLINE(void) ASMAtomicUoAndU32(uint32_t volatile *pu32, uint32_t u32) +{ +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__("andl %1, %0\n\t" + : "=m" (*pu32) + : "ir" (u32), + "m" (*pu32)); +# else + __asm + { + mov eax, [u32] +# ifdef RT_ARCH_AMD64 + mov rdx, [pu32] + and [rdx], eax +# else + mov edx, [pu32] + and [edx], eax +# endif + } +# endif +} +#endif + + +/** + * Atomically And a signed 32-bit value, unordered. + * + * @param pi32 Pointer to the pointer variable to AND i32 with. + * @param i32 The value to AND *pi32 with. + */ +DECLINLINE(void) ASMAtomicUoAndS32(int32_t volatile *pi32, int32_t i32) +{ + ASMAtomicUoAndU32((uint32_t volatile *)pi32, (uint32_t)i32); +} + + +/** + * Atomically And an unsigned 64-bit value, unordered. + * + * @param pu64 Pointer to the pointer variable to AND u64 with. + * @param u64 The value to AND *pu64 with. + */ +#if RT_INLINE_ASM_EXTERNAL +DECLASM(void) ASMAtomicUoAndU64(uint64_t volatile *pu64, uint64_t u64); +#else +DECLINLINE(void) ASMAtomicUoAndU64(uint64_t volatile *pu64, uint64_t u64) +{ +# if RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64) + __asm__ __volatile__("andq %1, %0\n\t" + : "=m" (*pu64) + : "r" (u64), + "m" (*pu64)); +# else + for (;;) + { + uint64_t u64Old = ASMAtomicUoReadU64(pu64); + uint64_t u64New = u64Old & u64; + if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old)) + break; + ASMNopPause(); + } +# endif +} +#endif + + +/** + * Atomically And a signed 64-bit value, unordered. + * + * @param pi64 Pointer to the pointer variable to AND i64 with. + * @param i64 The value to AND *pi64 with. + */ +DECLINLINE(void) ASMAtomicUoAndS64(int64_t volatile *pi64, int64_t i64) +{ + ASMAtomicUoAndU64((uint64_t volatile *)pi64, (uint64_t)i64); +} + + /** @def RT_ASM_PAGE_SIZE * We try avoid dragging in iprt/param.h here. diff --git a/include/iprt/asmdefs.mac b/include/iprt/asmdefs.mac index 665c674b..0b363a56 100644 --- a/include/iprt/asmdefs.mac +++ b/include/iprt/asmdefs.mac @@ -3,7 +3,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; @@ -71,6 +71,11 @@ ; Make the mask for the given bit. %define RT_BIT(bit) (1 << bit) +;; +; Makes a 32-bit unsigned (not type safe, but whatever) out of four byte values. +%define RT_MAKE_U32_FROM_U8(b0, b1, b2, b3) ( (b3 << 24) | (b2 << 16) | (b1 << 8) | b0 ) + + ;; ; Align code, pad with INT3. %define ALIGNCODE(alignment) align alignment, db 0cch @@ -94,17 +99,19 @@ ;; ; Mangles the given name so it can be referenced using DECLASM() in the ; C/C++ world. -%ifdef RT_ARCH_X86 - %ifdef RT_OS_OS2 - %define NAME(name) _ %+ NAME_OVERLOAD(name) +%ifndef ASM_FORMAT_BIN + %ifdef RT_ARCH_X86 + %ifdef RT_OS_OS2 + %define NAME(name) _ %+ NAME_OVERLOAD(name) + %endif + %ifdef RT_OS_WINDOWS + %define NAME(name) _ %+ NAME_OVERLOAD(name) + %endif %endif - %ifdef RT_OS_WINDOWS + %ifdef RT_OS_DARWIN %define NAME(name) _ %+ NAME_OVERLOAD(name) %endif %endif -%ifdef RT_OS_DARWIN - %define NAME(name) _ %+ NAME_OVERLOAD(name) -%endif %ifndef NAME %define NAME(name) NAME_OVERLOAD(name) %endif @@ -112,9 +119,9 @@ ;; ; Mangles the given C name so it will _import_ the right symbol. %ifdef ASM_FORMAT_PE -%define IMPNAME(name) __imp_ %+ NAME(name) + %define IMPNAME(name) __imp_ %+ NAME(name) %else -%define IMPNAME(name) NAME(name) + %define IMPNAME(name) NAME(name) %endif ;; @@ -129,6 +136,17 @@ %define IMP(name) IMPNAME(name) %endif +;; +; Declares an imported object for use with IMP2. +; @note May change the current section! +%macro EXTERN_IMP2 1 + extern IMPNAME(%1) + BEGINDATA + %ifdef ASM_FORMAT_MACHO + g_Imp2_ %+ %1: RTCCPTR_DEF IMPNAME(%1) + %endif +%endmacro + ;; ; Gets the pointer to an imported object, version 2. %ifdef ASM_FORMAT_PE @@ -137,12 +155,19 @@ %else %define IMP2(name) dword [IMPNAME(name)] %endif -%else - %ifdef RT_ARCH_AMD64 - %define IMP2(name) IMPNAME(name) wrt rip - %else - %define IMP2(name) IMPNAME(name) +%elifdef ASM_FORMAT_ELF + %ifdef PIC + %ifdef RT_ARCH_AMD64 + %define IMP2(name) qword [rel IMPNAME(name) wrt ..got] + %else + %define IMP2(name) IMPNAME(name) wrt ..plt + %endif %endif +%elifdef ASM_FORMAT_MACHO + %define IMP2(name) RTCCPTR_PRE [g_Imp2_ %+ name xWrtRIP] +%endif +%ifndef IMP2 + %define IMP2(name) IMPNAME(name) %endif @@ -276,8 +301,8 @@ size NAME(%1 %+ _EndProc) 0 %ifdef ASM_FORMAT_MACHO %ifdef __YASM__ - [section .text] - [section .data] + section .text + section .data %endif %endif @@ -290,7 +315,7 @@ size NAME(%1 %+ _EndProc) 0 %endmacro %else %macro BEGINCODE 0 -[section .text] + section .text %endmacro %endif @@ -307,9 +332,9 @@ size NAME(%1 %+ _EndProc) 0 %else %macro BEGINCONST 0 %ifdef ASM_FORMAT_MACHO ;; @todo check the other guys too. - [section .rodata] + section .rodata %else - [section .text] + section .text %endif %endmacro %endif @@ -322,7 +347,7 @@ size NAME(%1 %+ _EndProc) 0 %endmacro %else %macro BEGINDATA 0 -[section .data] + section .data %endmacro %endif @@ -334,7 +359,7 @@ size NAME(%1 %+ _EndProc) 0 %endmacro %else %macro BEGINBSS 0 -[section .bss] + section .bss %endmacro %endif @@ -717,7 +742,7 @@ BEGINPROC RT_NOCRT(%1) -;; @def xS +;; @def xCB ; The stack unit size / The register unit size. ;; @def xSP @@ -748,7 +773,7 @@ BEGINPROC RT_NOCRT(%1) ; 'wrt rip' for AMD64 targets, nothing for x86 ones. %ifdef RT_ARCH_AMD64 - %define xS 8 + %define xCB 8 %define xSP rsp %define xBP rbp %define xAX rax @@ -759,7 +784,7 @@ BEGINPROC RT_NOCRT(%1) %define xSI rsi %define xWrtRIP wrt rip %else - %define xS 4 + %define xCB 4 %define xSP esp %define xBP ebp %define xAX eax @@ -771,4 +796,37 @@ BEGINPROC RT_NOCRT(%1) %define xWrtRIP %endif + +; +; Some simple compile time assertions. +; +; Note! Requires new kBuild to work. +; + +;; +; Structure size assertion macro. +%define AssertCompileSize(a_Type, a_Size) AssertCompileSizeML a_Type, a_Size +%macro AssertCompileSizeML 2, + %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES + %assign AssertVar_cbActual %1 %+ _size + %assign AssertVar_cbExpected %2 + %if AssertVar_cbActual != AssertVar_cbExpected + %error %1 is AssertVar_cbActual bytes instead of AssertVar_cbExpected + %endif + %endif +%endmacro + +;; +; Structure memember offset assertion macro. +%define AssertCompileMemberOffset(a_Type, a_Member, a_off) AssertCompileMemberOffsetML a_Type, a_Member, a_off +%macro AssertCompileMemberOffsetML 3, + %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES + %assign AssertVar_offActual %1 %+ . %+ %2 + %assign AssertVar_offExpected %3 + %if AssertVar_offActual != AssertVar_offExpected + %error %1 %+ . %+ %2 is at AssertVar_offActual instead of AssertVar_offExpected + %endif + %endif +%endmacro + %endif diff --git a/include/iprt/assert.h b/include/iprt/assert.h index ec1631d1..8b9fba04 100644 --- a/include/iprt/assert.h +++ b/include/iprt/assert.h @@ -297,6 +297,8 @@ RT_C_DECLS_END */ #ifdef __GNUC__ # define AssertCompileNS(expr) extern int RTASSERTVAR[1] __attribute__((unused)), RTASSERTVAR[(expr) ? 1 : 0] __attribute__((unused)) +#elif defined(__IBMC__) || defined(__IBMCPP__) +# define AssertCompileNS(expr) extern int RTASSERTVAR[(expr) ? 1 : 0] #else # define AssertCompileNS(expr) typedef int RTASSERTTYPE[(expr) ? 1 : 0] #endif @@ -312,6 +314,23 @@ RT_C_DECLS_END # define AssertCompile(expr) AssertCompileNS(expr) #endif +/** @def RTASSERT_OFFSET_OF() + * A offsetof() macro suitable for compile time assertions. + * Both GCC v4 and VisualAge for C++ v3.08 has trouble using RT_OFFSETOF. + */ +#if defined(__GNUC__) +# if __GNUC__ >= 4 +# define RTASSERT_OFFSET_OF(a_Type, a_Member) __builtin_offsetof(a_Type, a_Member) +# else +# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member) +# endif +#elif (defined(__IBMC__) || defined(__IBMCPP__)) && defined(RT_OS_OS2) +# define RTASSERT_OFFSET_OF(a_Type, a_Member) __offsetof(a_Type, a_Member) +#else +# define RTASSERT_OFFSET_OF(a_Type, a_Member) RT_OFFSETOF(a_Type, a_Member) +#endif + + /** @def AssertCompileSize * Asserts a size at compile. * @param type The type. @@ -352,18 +371,8 @@ RT_C_DECLS_END * @param member The member. * @param align The member offset alignment to assert. */ -#if defined(__GNUC__) -# if __GNUC__ >= 4 -# define AssertCompileMemberAlignment(type, member, align) \ - AssertCompile(!(__builtin_offsetof(type, member) & ((align) - 1))) -# else -# define AssertCompileMemberAlignment(type, member, align) \ - AssertCompile(!(RT_OFFSETOF(type, member) & ((align) - 1))) -# endif -#else -# define AssertCompileMemberAlignment(type, member, align) \ - AssertCompile(!(RT_OFFSETOF(type, member) & ((align) - 1))) -#endif +#define AssertCompileMemberAlignment(type, member, align) \ + AssertCompile(!(RTASSERT_OFFSET_OF(type, member) & ((align) - 1))) /** @def AssertCompileMemberOffset * Asserts an offset of a structure member at compile. @@ -371,18 +380,8 @@ RT_C_DECLS_END * @param member The member. * @param off The expected offset. */ -#if defined(__GNUC__) -# if __GNUC__ >= 4 -# define AssertCompileMemberOffset(type, member, off) \ - AssertCompile(__builtin_offsetof(type, member) == (off)) -# else -# define AssertCompileMemberOffset(type, member, off) \ - AssertCompile(RT_OFFSETOF(type, member) == (off)) -# endif -#else -# define AssertCompileMemberOffset(type, member, off) \ - AssertCompile(RT_OFFSETOF(type, member) == (off)) -#endif +#define AssertCompileMemberOffset(type, member, off) \ + AssertCompile(RTASSERT_OFFSET_OF(type, member) == (off)) /** @def AssertCompile2MemberOffsets * Asserts that two (sub-structure) members in union have the same offset. @@ -390,18 +389,8 @@ RT_C_DECLS_END * @param member1 The first member. * @param member2 The second member. */ -#if defined(__GNUC__) -# if __GNUC__ >= 4 -# define AssertCompile2MemberOffsets(type, member1, member2) \ - AssertCompile(__builtin_offsetof(type, member1) == __builtin_offsetof(type, member2)) -# else -# define AssertCompile2MemberOffsets(type, member1, member2) \ - AssertCompile(RT_OFFSETOF(type, member1) == RT_OFFSETOF(type, member2)) -# endif -#else -# define AssertCompile2MemberOffsets(type, member1, member2) \ - AssertCompile(RT_OFFSETOF(type, member1) == RT_OFFSETOF(type, member2)) -#endif +#define AssertCompile2MemberOffsets(type, member1, member2) \ + AssertCompile(RTASSERT_OFFSET_OF(type, member1) == RTASSERT_OFFSET_OF(type, member2)) /** @def AssertCompileAdjacentMembers * Asserts that two structure members are adjacent. @@ -409,18 +398,8 @@ RT_C_DECLS_END * @param member1 The first member. * @param member2 The second member. */ -#if defined(__GNUC__) -# if __GNUC__ >= 4 -# define AssertCompileAdjacentMembers(type, member1, member2) \ - AssertCompile(__builtin_offsetof(type, member1) + RT_SIZEOFMEMB(type, member1) == __builtin_offsetof(type, member2)) -# else -# define AssertCompileAdjacentMembers(type, member1, member2) \ - AssertCompile(RT_OFFSETOF(type, member1) + RT_SIZEOFMEMB(type, member1) == RT_OFFSETOF(type, member2)) -# endif -#else -# define AssertCompileAdjacentMembers(type, member1, member2) \ - AssertCompile(RT_OFFSETOF(type, member1) + RT_SIZEOFMEMB(type, member1) == RT_OFFSETOF(type, member2)) -#endif +#define AssertCompileAdjacentMembers(type, member1, member2) \ + AssertCompile(RTASSERT_OFFSET_OF(type, member1) + RT_SIZEOFMEMB(type, member1) == RTASSERT_OFFSET_OF(type, member2)) /** @def AssertCompileMembersAtSameOffset * Asserts that members of two different structures are at the same offset. @@ -429,18 +408,8 @@ RT_C_DECLS_END * @param type2 The second type. * @param member2 The second member. */ -#if defined(__GNUC__) -# if __GNUC__ >= 4 -# define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \ - AssertCompile(__builtin_offsetof(type1, member1) == __builtin_offsetof(type2, member2)) -# else -# define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \ - AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2)) -# endif -#else -# define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \ - AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2)) -#endif +#define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \ + AssertCompile(RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2)) /** @def AssertCompileMembersSameSize * Asserts that members of two different structures have the same size. @@ -460,18 +429,9 @@ RT_C_DECLS_END * @param type2 The second type. * @param member2 The second member. */ -#if defined(__GNUC__) -# if __GNUC__ >= 4 -# define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \ - AssertCompile(__builtin_offsetof(type1, member1) == __builtin_offsetof(type2, member2) && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2)) -# else -# define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \ - AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2) && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2)) -# endif -#else -# define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \ - AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2) && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2)) -#endif +#define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \ + AssertCompile( RTASSERT_OFFSET_OF(type1, member1) == RTASSERT_OFFSET_OF(type2, member2) \ + && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2)) /** @} */ @@ -504,7 +464,7 @@ RT_C_DECLS_END * @remarks This macro does not depend on RT_STRICT. */ #if defined(IN_RING0) \ - && (defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)) + && (defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS)) # define RTAssertDoPanic() RTR0AssertPanicSystem() #else # define RTAssertDoPanic() RTAssertDebugBreak() @@ -1511,6 +1471,23 @@ RT_C_DECLS_END RTAssertPanic(); \ } while (0) +/** @def AssertLogRelMsgFailedStmt + * An assertion failed, execute @a stmt. + * + * Strict builds will hit a breakpoint, non-strict will only do LogRel. The + * statement will be executed in regardless of build type. + * + * @param a printf argument list (in parenthesis). + * @param stmt Statement to execute after raising/logging the assertion. + */ +#define AssertLogRelMsgFailedStmt(a, stmt) \ + do { \ + RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \ + RTAssertLogRelMsg2(a); \ + RTAssertPanic(); \ + stmt; \ + } while (0) + /** @def AssertLogRelMsgFailedReturn * An assertion failed, return \a rc. * Strict builds will hit a breakpoint, non-strict will only do LogRel. diff --git a/include/iprt/avl.h b/include/iprt/avl.h index 9c1b99df..2347b80e 100644 --- a/include/iprt/avl.h +++ b/include/iprt/avl.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 1999-2003 knut st. osmundsen + * Copyright (C) 1999-2012 knut st. osmundsen * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -62,7 +62,8 @@ typedef PAVLPVNODECORE AVLPVTREE; /** Pointer to a tree with void pointer keys. */ typedef PPAVLPVNODECORE PAVLPVTREE; -/** Callback function for AVLPVDoWithAll(). */ +/** Callback function for AVLPVDoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLPVCALLBACK(PAVLPVNODECORE, void *); /** Pointer to callback function for AVLPVDoWithAll(). */ typedef AVLPVCALLBACK *PAVLPVCALLBACK; @@ -102,7 +103,8 @@ typedef struct _AVLULNodeCore } AVLULNODECORE, *PAVLULNODECORE, **PPAVLULNODECORE; -/** Callback function for AVLULDoWithAll(). */ +/** Callback function for AVLULDoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLULCALLBACK(PAVLULNODECORE, void*); /** Pointer to callback function for AVLULDoWithAll(). */ typedef AVLULCALLBACK *PAVLULCALLBACK; @@ -149,7 +151,8 @@ typedef PAVLRPVNODECORE AVLRPVTREE; /** Pointer to a tree with void pointer keys. */ typedef PPAVLRPVNODECORE PAVLRPVTREE; -/** Callback function for AVLPVDoWithAll(). */ +/** Callback function for AVLPVDoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLRPVCALLBACK(PAVLRPVNODECORE, void *); /** Pointer to callback function for AVLPVDoWithAll(). */ typedef AVLRPVCALLBACK *PAVLRPVCALLBACK; @@ -192,7 +195,8 @@ typedef PAVLU32NODECORE AVLU32TREE; /** Pointer to a tree with void pointer keys. */ typedef PPAVLU32NODECORE PAVLU32TREE; -/** Callback function for AVLU32DoWithAll() & AVLU32Destroy(). */ +/** Callback function for AVLU32DoWithAll() & AVLU32Destroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLU32CALLBACK(PAVLU32NODECORE, void*); /** Pointer to callback function for AVLU32DoWithAll() & AVLU32Destroy(). */ typedef AVLU32CALLBACK *PAVLU32CALLBACK; @@ -242,7 +246,8 @@ typedef AVLOU32TREE *PAVLOU32TREE; * In this case it's a pointer to a relative offset. */ typedef AVLOU32TREE *PPAVLOU32NODECORE; -/** Callback function for RTAvloU32DoWithAll(). */ +/** Callback function for RTAvloU32DoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLOU32CALLBACK(PAVLOU32NODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvloU32DoWithAll(). */ typedef AVLOU32CALLBACK *PAVLOU32CALLBACK; @@ -275,7 +280,8 @@ typedef struct _AVLLU32NodeCore struct _AVLLU32NodeCore *pList; /**< Pointer to next node with the same key. */ } AVLLU32NODECORE, *PAVLLU32NODECORE, **PPAVLLU32NODECORE; -/** Callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */ +/** Callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLLU32CALLBACK(PAVLLU32NODECORE, void*); /** Pointer to callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */ typedef AVLLU32CALLBACK *PAVLLU32CALLBACK; @@ -323,7 +329,8 @@ typedef PAVLRU64NODECORE AVLRU64TREE; /** Pointer to a tree with void pointer keys. */ typedef PPAVLRU64NODECORE PAVLRU64TREE; -/** Callback function for AVLRU64DoWithAll(). */ +/** Callback function for AVLRU64DoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLRU64CALLBACK(PAVLRU64NODECORE, void *); /** Pointer to callback function for AVLU64DoWithAll(). */ typedef AVLRU64CALLBACK *PAVLRU64CALLBACK; @@ -380,7 +387,8 @@ typedef AVLOGCPHYSTREE *PAVLOGCPHYSTREE; * In this case it's a pointer to a relative offset. */ typedef AVLOGCPHYSTREE *PPAVLOGCPHYSNODECORE; -/** Callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy(). */ +/** Callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLOGCPHYSCALLBACK(PAVLOGCPHYSNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy(). */ typedef AVLOGCPHYSCALLBACK *PAVLOGCPHYSCALLBACK; @@ -433,7 +441,8 @@ typedef AVLROGCPHYSTREE *PAVLROGCPHYSTREE; * In this case it's a pointer to a relative offset. */ typedef AVLROGCPHYSTREE *PPAVLROGCPHYSNODECORE; -/** Callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy(). */ +/** Callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLROGCPHYSCALLBACK(PAVLROGCPHYSNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy(). */ typedef AVLROGCPHYSCALLBACK *PAVLROGCPHYSCALLBACK; @@ -477,7 +486,8 @@ typedef PAVLGCPTRNODECORE AVLGCPTRTREE; /** Pointer to a tree of RTGCPTR keys. */ typedef PPAVLGCPTRNODECORE PAVLGCPTRTREE; -/** Callback function for RTAvlGCPtrDoWithAll(). */ +/** Callback function for RTAvlGCPtrDoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLGCPTRCALLBACK(PAVLGCPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlGCPtrDoWithAll(). */ typedef AVLGCPTRCALLBACK *PAVLGCPTRCALLBACK; @@ -527,7 +537,8 @@ typedef AVLOGCPTRTREE *PAVLOGCPTRTREE; * In this case it's a pointer to a relative offset. */ typedef AVLOGCPTRTREE *PPAVLOGCPTRNODECORE; -/** Callback function for RTAvloGCPtrDoWithAll(). */ +/** Callback function for RTAvloGCPtrDoWithAll(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLOGCPTRCALLBACK(PAVLOGCPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvloGCPtrDoWithAll(). */ typedef AVLOGCPTRCALLBACK *PAVLOGCPTRCALLBACK; @@ -573,7 +584,8 @@ typedef AVLRGCPTRTREE *PAVLRGCPTRTREE; * In this case it's a pointer to a relative offset. */ typedef AVLRGCPTRTREE *PPAVLRGCPTRNODECORE; -/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */ +/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLRGCPTRCALLBACK(PAVLRGCPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */ typedef AVLRGCPTRCALLBACK *PAVLRGCPTRCALLBACK; @@ -629,7 +641,8 @@ typedef AVLROGCPTRTREE *PAVLROGCPTRTREE; * In this case it's a pointer to a relative offset. */ typedef AVLROGCPTRTREE *PPAVLROGCPTRNODECORE; -/** Callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy(). */ +/** Callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLROGCPTRCALLBACK(PAVLROGCPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy(). */ typedef AVLROGCPTRCALLBACK *PAVLROGCPTRCALLBACK; @@ -686,7 +699,8 @@ typedef AVLROOGCPTRTREE *PAVLROOGCPTRTREE; * In this case it's a pointer to a relative offset. */ typedef AVLROOGCPTRTREE *PPAVLROOGCPTRNODECORE; -/** Callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy(). */ +/** Callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLROOGCPTRCALLBACK(PAVLROOGCPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy(). */ typedef AVLROOGCPTRCALLBACK *PAVLROOGCPTRCALLBACK; @@ -737,7 +751,8 @@ typedef AVLUINTPTRTREE *PAVLUINTPTRTREE; * In this case it's a pointer to a pointer. */ typedef AVLUINTPTRTREE *PPAVLUINTPTRNODECORE; -/** Callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */ +/** Callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLUINTPTRCALLBACK(PAVLUINTPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */ typedef AVLUINTPTRCALLBACK *PAVLUINTPTRCALLBACK; @@ -787,7 +802,8 @@ typedef AVLRUINTPTRTREE *PAVLRUINTPTRTREE; * In this case it's a pointer to a pointer. */ typedef AVLRUINTPTRTREE *PPAVLRUINTPTRNODECORE; -/** Callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy(). */ +/** Callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLRUINTPTRCALLBACK(PAVLRUINTPTRNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy(). */ typedef AVLRUINTPTRCALLBACK *PAVLRUINTPTRCALLBACK; @@ -843,7 +859,8 @@ typedef AVLOHCPHYSTREE *PAVLOHCPHYSTREE; * In this case it's a pointer to a relative offset. */ typedef AVLOHCPHYSTREE *PPAVLOHCPHYSNODECORE; -/** Callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy(). */ +/** Callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLOHCPHYSCALLBACK(PAVLOHCPHYSNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy(). */ typedef AVLOHCPHYSCALLBACK *PAVLOHCPHYSCALLBACK; @@ -893,7 +910,8 @@ typedef AVLOIOPORTTREE *PAVLOIOPORTTREE; * In this case it's a pointer to a relative offset. */ typedef AVLOIOPORTTREE *PPAVLOIOPORTNODECORE; -/** Callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy(). */ +/** Callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLOIOPORTCALLBACK(PAVLOIOPORTNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy(). */ typedef AVLOIOPORTCALLBACK *PAVLOIOPORTCALLBACK; @@ -944,7 +962,8 @@ typedef AVLROIOPORTTREE *PAVLROIOPORTTREE; * In this case it's a pointer to a relative offset. */ typedef AVLROIOPORTTREE *PPAVLROIOPORTNODECORE; -/** Callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy(). */ +/** Callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLROIOPORTCALLBACK(PAVLROIOPORTNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy(). */ typedef AVLROIOPORTCALLBACK *PAVLROIOPORTCALLBACK; @@ -993,7 +1012,8 @@ typedef AVLHCPHYSTREE *PAVLHCPHYSTREE; * In this case it's a pointer to a relative offset. */ typedef AVLHCPHYSTREE *PPAVLHCPHYSNODECORE; -/** Callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy(). */ +/** Callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLHCPHYSCALLBACK(PAVLHCPHYSNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy(). */ typedef AVLHCPHYSCALLBACK *PAVLHCPHYSCALLBACK; @@ -1041,7 +1061,8 @@ typedef AVLGCPHYSTREE *PAVLGCPHYSTREE; * In this case it's a pointer to a relative offset. */ typedef AVLGCPHYSTREE *PPAVLGCPHYSNODECORE; -/** Callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy(). */ +/** Callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLGCPHYSCALLBACK(PAVLGCPHYSNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy(). */ typedef AVLGCPHYSCALLBACK *PAVLGCPHYSCALLBACK; @@ -1087,7 +1108,8 @@ typedef AVLRFOFFTREE *PAVLRFOFFTREE; * In this case it's a pointer to a relative offset. */ typedef AVLRFOFFTREE *PPAVLRFOFFNODECORE; -/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */ +/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). + * @returns IPRT status codes. */ typedef DECLCALLBACK(int) AVLRFOFFCALLBACK(PAVLRFOFFNODECORE pNode, void *pvUser); /** Pointer to callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */ typedef AVLRFOFFCALLBACK *PAVLRFOFFCALLBACK; diff --git a/include/iprt/base64.h b/include/iprt/base64.h index b52f48e1..dfbbc134 100644 --- a/include/iprt/base64.h +++ b/include/iprt/base64.h @@ -3,7 +3,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/include/iprt/buildconfig.h b/include/iprt/buildconfig.h index 9e4a9c57..8853fb80 100644 --- a/include/iprt/buildconfig.h +++ b/include/iprt/buildconfig.h @@ -3,7 +3,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/include/iprt/cdefs.h b/include/iprt/cdefs.h index db52defa..744fd48b 100644 --- a/include/iprt/cdefs.h +++ b/include/iprt/cdefs.h @@ -3,7 +3,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; @@ -31,16 +31,6 @@ * @{ */ -/* - * Include sys/cdefs.h if present, if not define the stuff we need. - */ -#ifdef HAVE_SYS_CDEFS_H -# if defined(RT_ARCH_LINUX) && defined(__KERNEL__) -# error "oops" -# endif -# include -#else - /** @def RT_C_DECLS_BEGIN * Used to start a block of function declarations which are shared * between C and C++ program. @@ -51,14 +41,12 @@ * between C and C++ program. */ -# if defined(__cplusplus) -# define RT_C_DECLS_BEGIN extern "C" { -# define RT_C_DECLS_END } -# else -# define RT_C_DECLS_BEGIN -# define RT_C_DECLS_END -# endif - +#if defined(__cplusplus) +# define RT_C_DECLS_BEGIN extern "C" { +# define RT_C_DECLS_END } +#else +# define RT_C_DECLS_BEGIN +# define RT_C_DECLS_END #endif @@ -283,6 +271,321 @@ #endif + +/** @name RT_OPSYS_XXX - Operative System Identifiers. + * These are the value that the RT_OPSYS \#define can take. @{ + */ +/** Unknown OS. */ +#define RT_OPSYS_UNKNOWN 0 +/** OS Agnostic. */ +#define RT_OPSYS_AGNOSTIC 1 +/** Darwin - aka Mac OS X. */ +#define RT_OPSYS_DARWIN 2 +/** DragonFly BSD. */ +#define RT_OPSYS_DRAGONFLY 3 +/** DOS. */ +#define RT_OPSYS_DOS 4 +/** FreeBSD. */ +#define RT_OPSYS_FREEBSD 5 +/** Haiku. */ +#define RT_OPSYS_HAIKU 6 +/** Linux. */ +#define RT_OPSYS_LINUX 7 +/** L4. */ +#define RT_OPSYS_L4 8 +/** Minix. */ +#define RT_OPSYS_MINIX 9 +/** NetBSD. */ +#define RT_OPSYS_NETBSD 11 +/** Netware. */ +#define RT_OPSYS_NETWARE 12 +/** NT (native). */ +#define RT_OPSYS_NT 13 +/** OpenBSD. */ +#define RT_OPSYS_OPENBSD 14 +/** OS/2. */ +#define RT_OPSYS_OS2 15 +/** Plan 9. */ +#define RT_OPSYS_PLAN9 16 +/** QNX. */ +#define RT_OPSYS_QNX 17 +/** Solaris. */ +#define RT_OPSYS_SOLARIS 18 +/** UEFI. */ +#define RT_OPSYS_UEFI 19 +/** Windows. */ +#define RT_OPSYS_WINDOWS 20 +/** The max RT_OPSYS_XXX value (exclusive). */ +#define RT_OPSYS_MAX 21 +/** @} */ + +/** @def RT_OPSYS + * Indicates which OS we're targetting. It's a \#define with is + * assigned one of the RT_OPSYS_XXX defines above. + * + * So to test if we're on FreeBSD do the following: + * @code + * #if RT_OPSYS == RT_OPSYS_FREEBSD + * some_funky_freebsd_specific_stuff(); + * #endif + * @endcode + */ + +/* + * Set RT_OPSYS_XXX according to RT_OS_XXX. + * + * Search: #define RT_OPSYS_([A-Z0-9]+) .* + * Replace: # elif defined(RT_OS_\1)\n# define RT_OPSYS RT_OPSYS_\1 + */ +#ifndef RT_OPSYS +# if defined(RT_OS_UNKNOWN) +# define RT_OPSYS RT_OPSYS_UNKNOWN +# elif defined(RT_OS_AGNOSTIC) +# define RT_OPSYS RT_OPSYS_AGNOSTIC +# elif defined(RT_OS_DARWIN) +# define RT_OPSYS RT_OPSYS_DARWIN +# elif defined(RT_OS_DRAGONFLY) +# define RT_OPSYS RT_OPSYS_DRAGONFLY +# elif defined(RT_OS_DOS) +# define RT_OPSYS RT_OPSYS_DOS +# elif defined(RT_OS_FREEBSD) +# define RT_OPSYS RT_OPSYS_FREEBSD +# elif defined(RT_OS_HAIKU) +# define RT_OPSYS RT_OPSYS_HAIKU +# elif defined(RT_OS_LINUX) +# define RT_OPSYS RT_OPSYS_LINUX +# elif defined(RT_OS_L4) +# define RT_OPSYS RT_OPSYS_L4 +# elif defined(RT_OS_MINIX) +# define RT_OPSYS RT_OPSYS_MINIX +# elif defined(RT_OS_NETBSD) +# define RT_OPSYS RT_OPSYS_NETBSD +# elif defined(RT_OS_NETWARE) +# define RT_OPSYS RT_OPSYS_NETWARE +# elif defined(RT_OS_NT) +# define RT_OPSYS RT_OPSYS_NT +# elif defined(RT_OS_OPENBSD) +# define RT_OPSYS RT_OPSYS_OPENBSD +# elif defined(RT_OS_OS2) +# define RT_OPSYS RT_OPSYS_OS2 +# elif defined(RT_OS_PLAN9) +# define RT_OPSYS RT_OPSYS_PLAN9 +# elif defined(RT_OS_QNX) +# define RT_OPSYS RT_OPSYS_QNX +# elif defined(RT_OS_SOLARIS) +# define RT_OPSYS RT_OPSYS_SOLARIS +# elif defined(RT_OS_UEFI) +# define RT_OPSYS RT_OPSYS_UEFI +# elif defined(RT_OS_WINDOWS) +# define RT_OPSYS RT_OPSYS_WINDOWS +# endif +#endif + +/* + * Guess RT_OPSYS based on compiler predefined macros. + */ +#ifndef RT_OPSYS +# if defined(__APPLE__) +# define RT_OPSYS RT_OPSYS_DARWIN +# elif defined(__DragonFly__) +# define RT_OPSYS RT_OPSYS_DRAGONFLY +# elif defined(__FreeBSD__) /*??*/ +# define RT_OPSYS RT_OPSYS_FREEBSD +# elif defined(__gnu_linux__) +# define RT_OPSYS RT_OPSYS_LINUX +# elif defined(__NetBSD__) /*??*/ +# define RT_OPSYS RT_OPSYS_NETBSD +# elif defined(__OpenBSD__) /*??*/ +# define RT_OPSYS RT_OPSYS_OPENBSD +# elif defined(__OS2__) +# define RT_OPSYS RT_OPSYS_OS2 +# elif defined(__sun__) || defined(__SunOS__) || defined(__sun) || defined(__SunOS) +# define RT_OPSYS RT_OPSYS_SOLARIS +# elif defined(_WIN32) || defined(_WIN64) +# define RT_OPSYS RT_OPSYS_WINDOWS +# else +# error "Port Me" +# endif +#endif + +#if RT_OPSYS < RT_OPSYS_UNKNOWN || RT_OPSYS >= RT_OPSYS_MAX +# error "Invalid RT_OPSYS value." +#endif + +/* + * Do some consistency checks. + * + * Search: #define RT_OPSYS_([A-Z0-9]+) .* + * Replace: #if defined(RT_OS_\1) && RT_OPSYS != RT_OPSYS_\1\n# error RT_OPSYS vs RT_OS_\1\n#endif + */ +#if defined(RT_OS_UNKNOWN) && RT_OPSYS != RT_OPSYS_UNKNOWN +# error RT_OPSYS vs RT_OS_UNKNOWN +#endif +#if defined(RT_OS_AGNOSTIC) && RT_OPSYS != RT_OPSYS_AGNOSTIC +# error RT_OPSYS vs RT_OS_AGNOSTIC +#endif +#if defined(RT_OS_DARWIN) && RT_OPSYS != RT_OPSYS_DARWIN +# error RT_OPSYS vs RT_OS_DARWIN +#endif +#if defined(RT_OS_DRAGONFLY) && RT_OPSYS != RT_OPSYS_DRAGONFLY +# error RT_OPSYS vs RT_OS_DRAGONFLY +#endif +#if defined(RT_OS_DOS) && RT_OPSYS != RT_OPSYS_DOS +# error RT_OPSYS vs RT_OS_DOS +#endif +#if defined(RT_OS_FREEBSD) && RT_OPSYS != RT_OPSYS_FREEBSD +# error RT_OPSYS vs RT_OS_FREEBSD +#endif +#if defined(RT_OS_HAIKU) && RT_OPSYS != RT_OPSYS_HAIKU +# error RT_OPSYS vs RT_OS_HAIKU +#endif +#if defined(RT_OS_LINUX) && RT_OPSYS != RT_OPSYS_LINUX +# error RT_OPSYS vs RT_OS_LINUX +#endif +#if defined(RT_OS_L4) && RT_OPSYS != RT_OPSYS_L4 +# error RT_OPSYS vs RT_OS_L4 +#endif +#if defined(RT_OS_MINIX) && RT_OPSYS != RT_OPSYS_MINIX +# error RT_OPSYS vs RT_OS_MINIX +#endif +#if defined(RT_OS_NETBSD) && RT_OPSYS != RT_OPSYS_NETBSD +# error RT_OPSYS vs RT_OS_NETBSD +#endif +#if defined(RT_OS_NETWARE) && RT_OPSYS != RT_OPSYS_NETWARE +# error RT_OPSYS vs RT_OS_NETWARE +#endif +#if defined(RT_OS_NT) && RT_OPSYS != RT_OPSYS_NT +# error RT_OPSYS vs RT_OS_NT +#endif +#if defined(RT_OS_OPENBSD) && RT_OPSYS != RT_OPSYS_OPENBSD +# error RT_OPSYS vs RT_OS_OPENBSD +#endif +#if defined(RT_OS_OS2) && RT_OPSYS != RT_OPSYS_OS2 +# error RT_OPSYS vs RT_OS_OS2 +#endif +#if defined(RT_OS_PLAN9) && RT_OPSYS != RT_OPSYS_PLAN9 +# error RT_OPSYS vs RT_OS_PLAN9 +#endif +#if defined(RT_OS_QNX) && RT_OPSYS != RT_OPSYS_QNX +# error RT_OPSYS vs RT_OS_QNX +#endif +#if defined(RT_OS_SOLARIS) && RT_OPSYS != RT_OPSYS_SOLARIS +# error RT_OPSYS vs RT_OS_SOLARIS +#endif +#if defined(RT_OS_UEFI) && RT_OPSYS != RT_OPSYS_UEFI +# error RT_OPSYS vs RT_OS_UEFI +#endif +#if defined(RT_OS_WINDOWS) && RT_OPSYS != RT_OPSYS_WINDOWS +# error RT_OPSYS vs RT_OS_WINDOWS +#endif + +/* + * Make sure the RT_OS_XXX macro is defined. + * + * Search: #define RT_OPSYS_([A-Z0-9]+) .* + * Replace: #elif RT_OPSYS == RT_OPSYS_\1\n# ifndef RT_OS_\1\n# define RT_OS_\1\n# endif + */ +#if RT_OPSYS == RT_OPSYS_UNKNOWN +# ifndef RT_OS_UNKNOWN +# define RT_OS_UNKNOWN +# endif +#elif RT_OPSYS == RT_OPSYS_AGNOSTIC +# ifndef RT_OS_AGNOSTIC +# define RT_OS_AGNOSTIC +# endif +#elif RT_OPSYS == RT_OPSYS_DARWIN +# ifndef RT_OS_DARWIN +# define RT_OS_DARWIN +# endif +#elif RT_OPSYS == RT_OPSYS_DRAGONFLY +# ifndef RT_OS_DRAGONFLY +# define RT_OS_DRAGONFLY +# endif +#elif RT_OPSYS == RT_OPSYS_DOS +# ifndef RT_OS_DOS +# define RT_OS_DOS +# endif +#elif RT_OPSYS == RT_OPSYS_FREEBSD +# ifndef RT_OS_FREEBSD +# define RT_OS_FREEBSD +# endif +#elif RT_OPSYS == RT_OPSYS_HAIKU +# ifndef RT_OS_HAIKU +# define RT_OS_HAIKU +# endif +#elif RT_OPSYS == RT_OPSYS_LINUX +# ifndef RT_OS_LINUX +# define RT_OS_LINUX +# endif +#elif RT_OPSYS == RT_OPSYS_L4 +# ifndef RT_OS_L4 +# define RT_OS_L4 +# endif +#elif RT_OPSYS == RT_OPSYS_MINIX +# ifndef RT_OS_MINIX +# define RT_OS_MINIX +# endif +#elif RT_OPSYS == RT_OPSYS_NETBSD +# ifndef RT_OS_NETBSD +# define RT_OS_NETBSD +# endif +#elif RT_OPSYS == RT_OPSYS_NETWARE +# ifndef RT_OS_NETWARE +# define RT_OS_NETWARE +# endif +#elif RT_OPSYS == RT_OPSYS_NT +# ifndef RT_OS_NT +# define RT_OS_NT +# endif +#elif RT_OPSYS == RT_OPSYS_OPENBSD +# ifndef RT_OS_OPENBSD +# define RT_OS_OPENBSD +# endif +#elif RT_OPSYS == RT_OPSYS_OS2 +# ifndef RT_OS_OS2 +# define RT_OS_OS2 +# endif +#elif RT_OPSYS == RT_OPSYS_PLAN9 +# ifndef RT_OS_PLAN9 +# define RT_OS_PLAN9 +# endif +#elif RT_OPSYS == RT_OPSYS_QNX +# ifndef RT_OS_QNX +# define RT_OS_QNX +# endif +#elif RT_OPSYS == RT_OPSYS_SOLARIS +# ifndef RT_OS_SOLARIS +# define RT_OS_SOLARIS +# endif +#elif RT_OPSYS == RT_OPSYS_UEFI +# ifndef RT_OS_UEFI +# define RT_OS_UEFI +# endif +#elif RT_OPSYS == RT_OPSYS_WINDOWS +# ifndef RT_OS_WINDOWS +# define RT_OS_WINDOWS +# endif +#else +# error "Bad RT_OPSYS value." +#endif + + +/** + * Checks whether the given OpSys uses DOS-style paths or not. + * + * By DOS-style paths we include drive lettering and UNC paths. + * + * @returns true / false + * @param a_OpSys The RT_OPSYS_XXX value to check, will be reference + * multiple times. + */ +#define RT_OPSYS_USES_DOS_PATHS(a_OpSys) \ + ( (a_OpSys) == RT_OPSYS_WINDOWS \ + || (a_OpSys) == RT_OPSYS_OS2 \ + || (a_OpSys) == RT_OPSYS_DOS ) + + + /** @def CTXTYPE * Declare a type differently in GC, R3 and R0. * @@ -762,14 +1065,22 @@ * @param type The return type of the function declaration. * @param name The name of the variable member. */ -#define DECLCALLBACKPTR(type, name) type (RTCALL * name) +#if defined(__IBMC__) || defined(__IBMCPP__) +# define DECLCALLBACKPTR(type, name) type (* RTCALL name) +#else +# define DECLCALLBACKPTR(type, name) type (RTCALL * name) +#endif /** @def DECLCALLBACKMEMBER * How to declare an call back function pointer member. * @param type The return type of the function declaration. * @param name The name of the struct/union/class member. */ -#define DECLCALLBACKMEMBER(type, name) type (RTCALL * name) +#if defined(__IBMC__) || defined(__IBMCPP__) +# define DECLCALLBACKMEMBER(type, name) type (* RTCALL name) +#else +# define DECLCALLBACKMEMBER(type, name) type (RTCALL * name) +#endif /** @def DECLR3CALLBACKMEMBER * How to declare an call back function pointer member - R3 Ptr. @@ -778,7 +1089,7 @@ * @param args The argument list enclosed in parentheses. */ #ifdef IN_RING3 -# define DECLR3CALLBACKMEMBER(type, name, args) type (RTCALL * name) args +# define DECLR3CALLBACKMEMBER(type, name, args) DECLCALLBACKMEMBER(type, name) args #else # define DECLR3CALLBACKMEMBER(type, name, args) RTR3PTR name #endif @@ -790,7 +1101,7 @@ * @param args The argument list enclosed in parentheses. */ #ifdef IN_RC -# define DECLRCCALLBACKMEMBER(type, name, args) type (RTCALL * name) args +# define DECLRCCALLBACKMEMBER(type, name, args) DECLCALLBACKMEMBER(type, name) args #else # define DECLRCCALLBACKMEMBER(type, name, args) RTRCPTR name #endif @@ -802,7 +1113,7 @@ * @param args The argument list enclosed in parentheses. */ #ifdef IN_RING0 -# define DECLR0CALLBACKMEMBER(type, name, args) type (RTCALL * name) args +# define DECLR0CALLBACKMEMBER(type, name, args) DECLCALLBACKMEMBER(type, name) args #else # define DECLR0CALLBACKMEMBER(type, name, args) RTR0PTR name #endif @@ -1093,6 +1404,14 @@ #define RT_STR_TUPLE(a_szConst) a_szConst, (sizeof(a_szConst) - 1) +/** + * Macro for using in switch statements that turns constants into strings. + * + * @param a_Const The constant (not string). + */ +#define RT_CASE_RET_STR(a_Const) case a_Const: return #a_Const + + /** @def RT_BIT * Convert a bit number into an integer bitmask (unsigned). * @param bit The bit number. @@ -1362,9 +1681,9 @@ /** @def RT_LO_U16 * Gets the low uint16_t of a uint32_t or something equivalent. */ #ifdef __GNUC__ -# define RT_LO_U16(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)(a); }) +# define RT_LO_U16(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint32_t)); (uint16_t)(a); }) #else -# define RT_LO_U16(a) ( (uint32_t)(a) ) +# define RT_LO_U16(a) ( (uint16_t)(a) ) #endif /** @def RT_HI_U16 * Gets the high uint16_t of a uint32_t or something equivalent). */ @@ -2332,10 +2651,17 @@ #endif /** @def RT_INLINE_ASM_USES_INTRIN - * Defined as 1 if the compiler have and uses intrin.h. Otherwise it is 0. */ + * Defined as the major MSC version if the compiler have and uses intrin.h. + * Otherwise it is 0. */ #ifdef _MSC_VER -# if _MSC_VER >= 1400 -# define RT_INLINE_ASM_USES_INTRIN 1 +# if _MSC_VER >= 1700 /* Visual C++ v11.0 / 2012 */ +# define RT_INLINE_ASM_USES_INTRIN 17 +# elif _MSC_VER >= 1600 /* Visual C++ v10.0 / 2010 */ +# define RT_INLINE_ASM_USES_INTRIN 16 +# elif _MSC_VER >= 1500 /* Visual C++ v9.0 / 2008 */ +# define RT_INLINE_ASM_USES_INTRIN 15 +# elif _MSC_VER >= 1400 /* Visual C++ v8.0 / 2005 */ +# define RT_INLINE_ASM_USES_INTRIN 14 # endif #endif #ifndef RT_INLINE_ASM_USES_INTRIN diff --git a/include/iprt/cidr.h b/include/iprt/cidr.h index 5e054186..8e56453c 100644 --- a/include/iprt/cidr.h +++ b/include/iprt/cidr.h @@ -3,7 +3,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; @@ -29,6 +29,7 @@ #include #include +#include /** @defgroup grp_rt_cidr RTCidr - Classless Inter-Domain Routing notation * @ingroup grp_rt @@ -36,14 +37,6 @@ */ RT_C_DECLS_BEGIN -/** An IPv4 address. */ -typedef uint32_t RTIPV4ADDR; -/** Pointer to an IPv4 address. */ -typedef RTIPV4ADDR *PRTIPV4ADDR; -/** Pointer to a const IPv4 address. */ -typedef RTIPV4ADDR const *PCRTIPV4ADDR; - - /** * Parse a string which contains an IP address in CIDR (Classless Inter-Domain Routing) notation. * @@ -53,7 +46,7 @@ typedef RTIPV4ADDR const *PCRTIPV4ADDR; * @param pNetwork The determined IP address / network. * @param pNetmask The determined netmask. */ -RTDECL(int) RTCidrStrToIPv4(const char *pszAddress, PRTIPV4ADDR pNetwork, PRTIPV4ADDR pNetmask); +RTDECL(int) RTCidrStrToIPv4(const char *pszAddress, PRTNETADDRIPV4 pNetwork, PRTNETADDRIPV4 pNetmask); RT_C_DECLS_END /** @} */ diff --git a/include/iprt/circbuf.h b/include/iprt/circbuf.h index b0c58ffe..99f0d82e 100644 --- a/include/iprt/circbuf.h +++ b/include/iprt/circbuf.h @@ -3,7 +3,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/include/iprt/cpp/list.h b/include/iprt/cpp/list.h index 97c1a193..ca8c8f3c 100644 --- a/include/iprt/cpp/list.h +++ b/include/iprt/cpp/list.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -29,6 +29,7 @@ #include #include #include /* for memcpy */ +#include #include /* For std::bad_alloc */ @@ -133,16 +134,13 @@ class RTCListHelper public: static inline void set(T2 *p, size_t i, const T1 &v) { p[i] = v; } static inline T1 & at(T2 *p, size_t i) { return p[i]; } - static inline size_t find(T2 *p, const T1 &v, size_t cSize) + static inline size_t find(T2 *p, const T1 &v, size_t cElements) { - size_t i = 0; - while(i < cSize) - { + size_t i = cElements; + while (i-- > 0) if (p[i] == v) - break; - ++i; - } - return i; + return i; + return cElements; } static inline void copyTo(T2 *p, T2 *const p1 , size_t iTo, size_t cSize) { @@ -162,16 +160,13 @@ class RTCListHelper public: static inline void set(T1 **p, size_t i, const T1 &v) { p[i] = new T1(v); } static inline T1 & at(T1 **p, size_t i) { return *p[i]; } - static inline size_t find(T1 **p, const T1 &v, size_t cSize) + static inline size_t find(T1 **p, const T1 &v, size_t cElements) { - size_t i = 0; - while(i < cSize) - { + size_t i = cElements; + while (i-- > 0) if (*p[i] == v) - break; - ++i; - } - return i; + return i; + return cElements; } static inline void copyTo(T1 **p, T1 **const p1 , size_t iTo, size_t cSize) { @@ -179,10 +174,10 @@ public: p[iTo + i] = new T1(*p1[i]); } static inline void erase(T1 **p, size_t i) { delete p[i]; } - static inline void eraseRange(T1 **p, size_t cFrom, size_t cSize) + static inline void eraseRange(T1 **p, size_t iFrom, size_t cItems) { - for (size_t i = cFrom; i < cFrom + cSize; ++i) - delete p[i]; + while (cItems-- > 0) + delete p[iFrom++]; } }; @@ -194,15 +189,17 @@ public: template class RTCListBase { - /** - * Traits + /** @name Traits. * * Defines the return type of most of the getter methods. If the internal * used type is a pointer, we return a reference. If not we return by * value. + * + * @{ */ typedef typename RTCIfPtr::result GET_RTYPE; typedef typename RTCIfPtr::result GET_CRTYPE; + /** @} */ public: /** @@ -213,13 +210,13 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCListBase(size_t cCapacity = DefaultCapacity) - : m_pArray(0) - , m_cSize(0) - , m_cCapacity(0) + RTCListBase(size_t cCapacity = kDefaultCapacity) + : m_pArray(0) + , m_cElements(0) + , m_cCapacity(0) { if (cCapacity > 0) - realloc_grow(cCapacity); + growArray(cCapacity); } /** @@ -232,13 +229,18 @@ public: * @throws std::bad_alloc */ RTCListBase(const RTCListBase& other) - : m_pArray(0) - , m_cSize(0) - , m_cCapacity(0) + : m_pArray(0) + , m_cElements(0) + , m_cCapacity(0) { - realloc_no_elements_clean(other.m_cSize); - RTCListHelper::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize); - m_cSize = other.m_cSize; + other.m_guard.enterRead(); + + size_t const cElementsOther = other.m_cElements; + resizeArrayNoErase(cElementsOther); + RTCListHelper::copyTo(m_pArray, other.m_pArray, 0, cElementsOther); + m_cElements = cElementsOther; + + other.m_guard.leaveRead(); } /** @@ -246,16 +248,20 @@ public: */ ~RTCListBase() { - RTCListHelper::eraseRange(m_pArray, 0, m_cSize); + RTCListHelper::eraseRange(m_pArray, 0, m_cElements); if (m_pArray) + { RTMemFree(m_pArray); + m_pArray = NULL; + } + m_cElements = m_cCapacity = 0; } /** * Sets a new capacity within the list. * * If the new capacity is bigger than the old size, it will be simply - * preallocated more space for the new items. If the new capacity is + * preallocated more space for the new items. If the new capacity is * smaller than the previous size, items at the end of the list will be * deleted. * @@ -265,7 +271,7 @@ public: void setCapacity(size_t cCapacity) { m_guard.enterWrite(); - realloc(cCapacity); + resizeArray(cCapacity); m_guard.leaveWrite(); } @@ -274,26 +280,47 @@ public: * * @return The actual capacity. */ - size_t capacity() const { return m_cCapacity; } + size_t capacity() const + { + m_guard.enterRead(); + size_t cRet = m_cCapacity; + m_guard.leaveRead(); + return cRet; + } /** * Check if an list contains any items. * * @return True if there is more than zero items, false otherwise. */ - bool isEmpty() const { return m_cSize == 0; } + bool isEmpty() const + { + m_guard.enterRead(); + bool fEmpty = m_cElements == 0; + m_guard.leaveRead(); + return fEmpty; + } /** * Return the current count of elements within the list. * * @return The current element count. */ - size_t size() const { return m_cSize; } + size_t size() const + { + m_guard.enterRead(); + size_t cRet = m_cElements; + m_guard.leaveRead(); + return cRet; + } /** * Inserts an item to the list at position @a i. * - * @param i The position of the new item. + * @param i The position of the new item. The must be within or at the + * exact end of the list. Indexes specified beyond the end of + * the list will be changed to an append() operation and strict + * builds will raise an assert. * @param val The new item. * @return a reference to this list. * @throws std::bad_alloc @@ -301,13 +328,56 @@ public: RTCListBase &insert(size_t i, const T &val) { m_guard.enterWrite(); - if (m_cSize == m_cCapacity) - realloc_grow(m_cCapacity + DefaultCapacity); - memmove(&m_pArray[i + 1], &m_pArray[i], (m_cSize - i) * sizeof(ITYPE)); + + AssertMsgStmt(i <= m_cElements, ("i=%zu m_cElements=%zu\n", i, m_cElements), i = m_cElements); + + if (m_cElements == m_cCapacity) + growArray(m_cCapacity + kDefaultCapacity); + + memmove(&m_pArray[i + 1], &m_pArray[i], (m_cElements - i) * sizeof(ITYPE)); RTCListHelper::set(m_pArray, i, val); - ++m_cSize; + ++m_cElements; + m_guard.leaveWrite(); + return *this; + } + + /** + * Inserts a list to the list at position @a i. + * + * @param i The position of the new item. The must be within or at the + * exact end of the list. Indexes specified beyond the end of + * the list will be changed to an append() operation and strict + * builds will raise an assert. + * @param other The other list. This MUST not be the same as the destination + * list, will assert and return without doing anything if this + * happens. + * @return a reference to this list. + * @throws std::bad_alloc + */ + RTCListBase &insert(size_t i, const RTCListBase &other) + { + AssertReturn(this != &other, *this); + + other.m_guard.enterRead(); + m_guard.enterWrite(); + + AssertMsgStmt(i <= m_cElements, ("i=%zu m_cElements=%zu\n", i, m_cElements), i = m_cElements); + size_t cElementsOther = other.m_cElements; + if (RT_LIKELY(cElementsOther > 0)) + { + if (m_cCapacity - m_cElements < cElementsOther) + growArray(m_cCapacity + (cElementsOther - (m_cCapacity - m_cElements))); + if (i < m_cElements) + memmove(&m_pArray[i + cElementsOther], &m_pArray[i], (m_cElements - i) * sizeof(ITYPE)); + + RTCListHelper::copyTo(&m_pArray[i], other.m_pArray, 0, cElementsOther); + m_cElements += cElementsOther; + } + + m_guard.leaveWrite(); + other.m_guard.leaveRead(); return *this; } @@ -332,15 +402,7 @@ public: */ RTCListBase &prepend(const RTCListBase &other) { - m_guard.enterWrite(); - if (m_cCapacity - m_cSize < other.m_cSize) - realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize))); - memmove(&m_pArray[other.m_cSize], &m_pArray[0], m_cSize * sizeof(ITYPE)); - RTCListHelper::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize); - m_cSize += other.m_cSize; - m_guard.leaveWrite(); - - return *this; + return insert(0, other); } /** @@ -353,10 +415,10 @@ public: RTCListBase &append(const T &val) { m_guard.enterWrite(); - if (m_cSize == m_cCapacity) - realloc_grow(m_cCapacity + DefaultCapacity); - RTCListHelper::set(m_pArray, m_cSize, val); - ++m_cSize; + if (m_cElements == m_cCapacity) + growArray(m_cCapacity + kDefaultCapacity); + RTCListHelper::set(m_pArray, m_cElements, val); + ++m_cElements; m_guard.leaveWrite(); return *this; @@ -365,28 +427,29 @@ public: /** * Append a list of type T to the list. * - * @param other The list to append. + * @param other The list to append. Must not be the same as the destination + * list, will assert and return without doing anything. * @return a reference to this list. * @throws std::bad_alloc */ RTCListBase &append(const RTCListBase &other) { + AssertReturn(this != &other, *this); + + other.m_guard.enterRead(); m_guard.enterWrite(); - if (RT_LIKELY(other.m_cSize > 0)) - { - if (m_cCapacity - m_cSize < other.m_cSize) - realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize))); - RTCListHelper::copyTo(m_pArray, other.m_pArray, m_cSize, other.m_cSize); - m_cSize += other.m_cSize; - } - m_guard.leaveWrite(); + insert(m_cElements, other); + + m_guard.leaveWrite(); + other.m_guard.leaveRead(); return *this; } /** - * Copy the items of the other list into this list. All previous items of - * this list are deleted. + * Copy the items of the other list into this list. + * + * All previous items of this list are deleted. * * @param other The list to copy. * @return a reference to this list. @@ -397,51 +460,61 @@ public: if (RT_UNLIKELY(this == &other)) return *this; + other.m_guard.enterRead(); m_guard.enterWrite(); + /* Delete all items. */ - RTCListHelper::eraseRange(m_pArray, 0, m_cSize); + RTCListHelper::eraseRange(m_pArray, 0, m_cElements); + /* Need we to realloc memory. */ - if (other.m_cSize != m_cCapacity) - realloc_no_elements_clean(other.m_cSize); - m_cSize = other.m_cSize; + if (other.m_cElements != m_cCapacity) + resizeArrayNoErase(other.m_cElements); + m_cElements = other.m_cElements; + /* Copy new items. */ - RTCListHelper::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize); - m_guard.leaveWrite(); + RTCListHelper::copyTo(m_pArray, other.m_pArray, 0, other.m_cElements); + m_guard.leaveWrite(); + other.m_guard.leaveRead(); return *this; } /** * Replace an item in the list. * - * @note No boundary checks are done. Make sure @a i is equal or greater zero - * and smaller than RTCList::size. - * - * @param i The position of the item to replace. + * @param i The position of the item to replace. If this is out of range, + * the request will be ignored, strict builds will assert. * @param val The new value. * @return a reference to this list. */ RTCListBase &replace(size_t i, const T &val) { m_guard.enterWrite(); - RTCListHelper::erase(m_pArray, i); - RTCListHelper::set(m_pArray, i, val); - m_guard.leaveWrite(); + if (i < m_cElements) + { + RTCListHelper::erase(m_pArray, i); + RTCListHelper::set(m_pArray, i, val); + } + else + AssertMsgFailed(("i=%zu m_cElements=%zu\n", i, m_cElements)); + + m_guard.leaveWrite(); return *this; } /** * Return the first item as constant object. * - * @note No boundary checks are done. Make sure there is at least one - * element. + * @return A reference or pointer to the first item. * - * @return The first item. + * @note No boundary checks are done. Make sure there is at least one + * element. */ GET_CRTYPE first() const { m_guard.enterRead(); + Assert(m_cElements > 0); GET_CRTYPE res = RTCListHelper::at(m_pArray, 0); m_guard.leaveRead(); return res; @@ -450,14 +523,15 @@ public: /** * Return the first item. * - * @note No boundary checks are done. Make sure there is at least one - * element. + * @return A reference or pointer to the first item. * - * @return The first item. + * @note No boundary checks are done. Make sure there is at least one + * element. */ GET_RTYPE first() { m_guard.enterRead(); + Assert(m_cElements > 0); GET_RTYPE res = RTCListHelper::at(m_pArray, 0); m_guard.leaveRead(); return res; @@ -466,15 +540,16 @@ public: /** * Return the last item as constant object. * - * @note No boundary checks are done. Make sure there is at least one - * element. + * @return A reference or pointer to the last item. * - * @return The last item. + * @note No boundary checks are done. Make sure there is at least one + * element. */ GET_CRTYPE last() const { m_guard.enterRead(); - GET_CRTYPE res = RTCListHelper::at(m_pArray, m_cSize - 1); + Assert(m_cElements > 0); + GET_CRTYPE res = RTCListHelper::at(m_pArray, m_cElements - 1); m_guard.leaveRead(); return res; } @@ -482,15 +557,16 @@ public: /** * Return the last item. * - * @note No boundary checks are done. Make sure there is at least one - * element. + * @return A reference or pointer to the last item. * - * @return The last item. + * @note No boundary checks are done. Make sure there is at least one + * element. */ GET_RTYPE last() { m_guard.enterRead(); - GET_RTYPE res = RTCListHelper::at(m_pArray, m_cSize - 1); + Assert(m_cElements > 0); + GET_RTYPE res = RTCListHelper::at(m_pArray, m_cElements - 1); m_guard.leaveRead(); return res; } @@ -498,15 +574,16 @@ public: /** * Return the item at position @a i as constant object. * - * @note No boundary checks are done. Make sure @a i is equal or greater zero - * and smaller than RTCList::size. - * - * @param i The position of the item to return. + * @param i The position of the item to return. This better not be out of + * bounds, however should it be the last element of the array + * will be return and strict builds will raise an assertion. + * Should the array be empty, a crash is very likely. * @return The item at position @a i. */ GET_CRTYPE at(size_t i) const { m_guard.enterRead(); + AssertMsgStmt(i < m_cElements, ("i=%zu m_cElements=%zu\n", i, m_cElements), i = m_cElements - 1); GET_CRTYPE res = RTCListHelper::at(m_pArray, i); m_guard.leaveRead(); return res; @@ -515,15 +592,16 @@ public: /** * Return the item at position @a i. * - * @note No boundary checks are done. Make sure @a i is equal or greater zero - * and smaller than RTCList::size. - * - * @param i The position of the item to return. + * @param i The position of the item to return. This better not be out of + * bounds, however should it be the last element of the array + * will be return and strict builds will raise an assertion. + * Should the array be empty, a crash is very likely. * @return The item at position @a i. */ GET_RTYPE at(size_t i) { m_guard.enterRead(); + AssertMsgStmt(i < m_cElements, ("i=%zu m_cElements=%zu\n", i, m_cElements), i = m_cElements - 1); GET_RTYPE res = RTCListHelper::at(m_pArray, i); m_guard.leaveRead(); return res; @@ -532,31 +610,31 @@ public: /** * Return the item at position @a i as mutable reference. * - * @note No boundary checks are done. Make sure @a i is equal or greater zero - * and smaller than RTCList::size. - * - * @param i The position of the item to return. + * @param i The position of the item to return. This better not be out of + * bounds, however should it be the last element of the array + * will be return and strict builds will raise an assertion. + * Should the array be empty, a crash is very likely. * @return The item at position @a i. */ T &operator[](size_t i) { m_guard.enterRead(); + AssertMsgStmt(i < m_cElements, ("i=%zu m_cElements=%zu\n", i, m_cElements), i = m_cElements - 1); T &res = RTCListHelper::at(m_pArray, i); m_guard.leaveRead(); return res; } /** - * Return the item at position @a i. If @a i isn't valid within the list a - * default value is returned. + * Return the item at position @a i or default value if out of range. * * @param i The position of the item to return. - * @return The item at position @a i. + * @return The item at position @a i or default value. */ T value(size_t i) const { m_guard.enterRead(); - if (RT_UNLIKELY(i >= m_cSize)) + if (RT_UNLIKELY(i >= m_cElements)) { m_guard.leaveRead(); return T(); @@ -567,17 +645,16 @@ public: } /** - * Return the item at position @a i. If @a i isn't valid within the list - * @a defaultVal is returned. + * Return the item at position @a i, or @a defaultVal if out of range. * * @param i The position of the item to return. * @param defaultVal The value to return in case @a i is invalid. - * @return The item at position @a i. + * @return The item at position @a i or @a defaultVal. */ T value(size_t i, const T &defaultVal) const { m_guard.enterRead(); - if (RT_UNLIKELY(i >= m_cSize)) + if (RT_UNLIKELY(i >= m_cElements)) { m_guard.leaveRead(); return defaultVal; @@ -596,16 +673,16 @@ public: bool contains(const T &val) const { m_guard.enterRead(); - bool res = RTCListHelper::find(m_pArray, val, m_cSize) != m_cSize; + bool fRc = RTCListHelper::find(m_pArray, val, m_cElements) < m_cElements; m_guard.leaveRead(); - return res; + return fRc; } /** * Remove the first item. * - * @note No boundary checks are done. Make sure there is at least one - * element. + * @note You should make sure the list isn't empty. Strict builds will assert. + * The other builds will quietly ignore the request. */ void removeFirst() { @@ -615,51 +692,52 @@ public: /** * Remove the last item. * - * @note No boundary checks are done. Make sure there is at least one - * element. + * @note You should make sure the list isn't empty. Strict builds will assert. + * The other builds will quietly ignore the request. */ void removeLast() { - removeAt(m_cSize - 1); + m_guard.enterWrite(); + removeAtLocked(m_cElements - 1); + m_guard.leaveWrite(); } /** * Remove the item at position @a i. * - * @note No boundary checks are done. Make sure @a i is equal or greater zero - * and smaller than RTCList::size. - * - * @param i The position of the item to remove. + * @param i The position of the item to remove. Out of bounds values will + * be ignored and an assertion will be raised in strict builds. */ void removeAt(size_t i) { m_guard.enterWrite(); - RTCListHelper::erase(m_pArray, i); - /* Not last element? */ - if (i < m_cSize - 1) - memmove(&m_pArray[i], &m_pArray[i + 1], (m_cSize - i - 1) * sizeof(ITYPE)); - --m_cSize; + removeAtLocked(i); m_guard.leaveWrite(); } /** * Remove a range of items from the list. * - * @note No boundary checks are done. Make sure @a iFrom is equal or - * greater zero and smaller than RTCList::size. @a iTo has to be - * greater than @a iFrom and equal or smaller than RTCList::size. - * - * @param iFrom The start position of the items to remove. - * @param iTo The end position of the items to remove (excluded). + * @param iStart The start position of the items to remove. + * @param iEnd The end position of the items to remove (excluded). */ - void removeRange(size_t iFrom, size_t iTo) + void removeRange(size_t iStart, size_t iEnd) { + AssertReturnVoid(iStart <= iEnd); m_guard.enterWrite(); - RTCListHelper::eraseRange(m_pArray, iFrom, iTo - iFrom); - /* Not last elements? */ - if (m_cSize - iTo > 0) - memmove(&m_pArray[iFrom], &m_pArray[iTo], (m_cSize - iTo) * sizeof(ITYPE)); - m_cSize -= iTo - iFrom; + + AssertMsgStmt(iEnd <= m_cElements, ("iEnd=%zu m_cElements=%zu\n", iEnd, m_cElements), iEnd = m_cElements); + AssertMsgStmt(iStart < m_cElements, ("iStart=%zu m_cElements=%zu\n", iStart, m_cElements), iStart = m_cElements); + size_t const cElements = iEnd - iStart; + if (cElements > 0) + { + Assert(iStart < m_cElements); + RTCListHelper::eraseRange(m_pArray, iStart, cElements); + if (m_cElements > iEnd) + memmove(&m_pArray[iStart], &m_pArray[iEnd], (m_cElements - iEnd) * sizeof(ITYPE)); + m_cElements -= cElements; + } + m_guard.leaveWrite(); } @@ -669,18 +747,21 @@ public: void clear() { m_guard.enterWrite(); + /* Values cleanup */ - RTCListHelper::eraseRange(m_pArray, 0, m_cSize); - if (m_cSize != DefaultCapacity) - realloc_no_elements_clean(DefaultCapacity); - m_cSize = 0; + RTCListHelper::eraseRange(m_pArray, 0, m_cElements); + if (m_cElements != kDefaultCapacity) + resizeArrayNoErase(kDefaultCapacity); + m_cElements = 0; + m_guard.leaveWrite(); } /** - * Return the raw array. For native types this is a pointer to continuous - * memory of the items. For pointer types this is a continuous memory of - * pointers to the items. + * Return the raw array. + * + * For native types this is a pointer to continuous memory of the items. For + * pointer types this is a continuous memory of pointers to the items. * * @warning If you change anything in the underlaying list, this memory * will very likely become invalid. So take care when using this @@ -688,12 +769,12 @@ public: * * @returns the raw memory. */ - ITYPE* raw() const + ITYPE *raw() const { m_guard.enterRead(); - ITYPE* res = m_pArray; + ITYPE *pRet = m_pArray; m_guard.leaveRead(); - return res; + return pRet; } RTCListBase &operator<<(const T &val) @@ -707,89 +788,114 @@ public: /** * The default capacity of the list. This is also used as grow factor. */ - static const size_t DefaultCapacity; + static const size_t kDefaultCapacity; protected: /** - * Generic realloc, which does some kind of boundary checking. + * Generic resizes the array, surplus elements are erased. + * + * @param cElementsNew The new array size. + * @throws std::bad_alloc. */ - void realloc(size_t cNewSize) + void resizeArray(size_t cElementsNew) { /* Same size? */ - if (cNewSize == m_cCapacity) + if (cElementsNew == m_cCapacity) return; /* If we get smaller we have to delete some of the objects at the end of the list. */ - if ( cNewSize < m_cSize + if ( cElementsNew < m_cElements && m_pArray) - RTCListHelper::eraseRange(m_pArray, cNewSize, m_cSize - cNewSize); - realloc_no_elements_clean(cNewSize); + RTCListHelper::eraseRange(m_pArray, cElementsNew, m_cElements - cElementsNew); + + resizeArrayNoErase(cElementsNew); } - void realloc_no_elements_clean(size_t cNewSize) + /** + * Resizes the array without doing the erase() thing on surplus elements. + * + * @param cElementsNew The new array size. + * @throws std::bad_alloc. + */ + void resizeArrayNoErase(size_t cElementsNew) { /* Same size? */ - if (cNewSize == m_cCapacity) + if (cElementsNew == m_cCapacity) return; - /* If we get smaller we have to delete some of the objects at the end - of the list. */ - if ( cNewSize < m_cSize - && m_pArray) - m_cSize -= m_cSize - cNewSize; - - /* If we get zero we delete the array it self. */ - if ( cNewSize == 0 - && m_pArray) - { - RTMemFree(m_pArray); - m_pArray = 0; - } - m_cCapacity = cNewSize; - /* Resize the array. */ - if (cNewSize > 0) + if (cElementsNew > 0) { - m_pArray = static_cast(RTMemRealloc(m_pArray, sizeof(ITYPE) * cNewSize)); - if (!m_pArray) + void *pvNew = RTMemRealloc(m_pArray, sizeof(ITYPE) * cElementsNew); + if (!pvNew) { - /** @todo you leak memory. */ - m_cCapacity = 0; - m_cSize = 0; #ifdef RT_EXCEPTIONS_ENABLED throw std::bad_alloc(); #endif + return; } + m_pArray = static_cast(pvNew); + } + /* If we get zero we delete the array it self. */ + else if (m_pArray) + { + RTMemFree(m_pArray); + m_pArray = NULL; } + + m_cCapacity = cElementsNew; + if (m_cElements > cElementsNew) + m_cElements = cElementsNew; } /** * Special realloc method which require that the array will grow. * + * @param cElementsNew The new array size. + * @throws std::bad_alloc. * @note No boundary checks are done! */ - void realloc_grow(size_t cNewSize) + void growArray(size_t cElementsNew) { - /* Resize the array. */ - m_cCapacity = cNewSize; - m_pArray = static_cast(RTMemRealloc(m_pArray, sizeof(ITYPE) * cNewSize)); - if (!m_pArray) + Assert(cElementsNew > m_cCapacity); + void *pvNew = RTMemRealloc(m_pArray, sizeof(ITYPE) * cElementsNew); + if (pvNew) + { + m_cCapacity = cElementsNew; + m_pArray = static_cast(pvNew); + } + else { - /** @todo you leak memory. */ - m_cCapacity = 0; - m_cSize = 0; #ifdef RT_EXCEPTIONS_ENABLED throw std::bad_alloc(); #endif } } + /** + * Remove the item at position @a i. + * + * @param i The position of the item to remove. Out of bounds values will + * be ignored and an assertion will be raised in strict builds. + * @remarks + */ + void removeAtLocked(size_t i) + { + AssertMsgReturnVoid(i < m_cElements, ("i=%zu m_cElements=%zu\n", i, m_cElements)); + + RTCListHelper::erase(m_pArray, i); + if (i < m_cElements - 1) + memmove(&m_pArray[i], &m_pArray[i + 1], (m_cElements - i - 1) * sizeof(ITYPE)); + --m_cElements; + } + + /** The internal list array. */ ITYPE *m_pArray; /** The current count of items in use. */ - size_t m_cSize; + size_t m_cElements; /** The current capacity of the internal array. */ size_t m_cCapacity; /** The guard used to serialize the access to the items. */ @@ -797,7 +903,7 @@ protected: }; template -const size_t RTCListBase::DefaultCapacity = 10; +const size_t RTCListBase::kDefaultCapacity = 10; /** * Template class which automatically determines the type of list to use. @@ -819,11 +925,11 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} RTCList(const BASE &other) - : BASE(other) {} + : BASE(other) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -850,8 +956,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -878,8 +984,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); diff --git a/include/iprt/cpp/ministring.h b/include/iprt/cpp/ministring.h index 29c97409..35984905 100644 --- a/include/iprt/cpp/ministring.h +++ b/include/iprt/cpp/ministring.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2011 Oracle Corporation + * Copyright (C) 2007-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; @@ -425,7 +425,7 @@ public: if (length()) { /* Folding an UTF-8 string may result in a shorter encoding (see - testcase), so recalculate the length afterwars. */ + testcase), so recalculate the length afterwards. */ ::RTStrToUpper(m_psz); size_t cchNew = strlen(m_psz); Assert(cchNew <= m_cch); @@ -444,7 +444,7 @@ public: if (length()) { /* Folding an UTF-8 string may result in a shorter encoding (see - testcase), so recalculate the length afterwars. */ + testcase), so recalculate the length afterwards. */ ::RTStrToLower(m_psz); size_t cchNew = strlen(m_psz); Assert(cchNew <= m_cch); diff --git a/include/iprt/cpp/mtlist.h b/include/iprt/cpp/mtlist.h index eb4e587c..de13464d 100644 --- a/include/iprt/cpp/mtlist.h +++ b/include/iprt/cpp/mtlist.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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; @@ -27,7 +27,6 @@ #define ___iprt_cpp_mtlist_h #include - #include /** @addtogroup grp_rt_cpp_list @@ -41,8 +40,26 @@ template <> class RTCListGuard { public: - RTCListGuard() { int rc = RTSemRWCreate(&m_hRWSem); AssertRC(rc); } - ~RTCListGuard() { RTSemRWDestroy(m_hRWSem); } + RTCListGuard() : m_hRWSem(NIL_RTSEMRW) + { +#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) + RTLOCKVALCLASS hClass; + int rc = RTLockValidatorClassCreate(&hClass, true /*fAutodidact*/, RT_SRC_POS, "RTCListGuard"); + AssertStmt(RT_SUCCESS(rc), hClass = NIL_RTLOCKVALCLASS); + rc = RTSemRWCreateEx(&m_hRWSem, 0 /*fFlags*/, hClass, RTLOCKVAL_SUB_CLASS_NONE, NULL /*pszNameFmt*/); + AssertRC(rc); +#else + int rc = RTSemRWCreateEx(&m_hRWSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, 0, NULL); + AssertRC(rc); +#endif + } + + ~RTCListGuard() + { + RTSemRWDestroy(m_hRWSem); + m_hRWSem = NIL_RTSEMRW; + } + inline void enterRead() const { int rc = RTSemRWRequestRead(m_hRWSem, RT_INDEFINITE_WAIT); AssertRC(rc); } inline void leaveRead() const { int rc = RTSemRWReleaseRead(m_hRWSem); AssertRC(rc); } inline void enterWrite() { int rc = RTSemRWRequestWrite(m_hRWSem, RT_INDEFINITE_WAIT); AssertRC(rc); } @@ -86,8 +103,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCMTList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -114,8 +131,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCMTList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -142,8 +159,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCMTList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); diff --git a/include/iprt/cpp/utils.h b/include/iprt/cpp/utils.h index e5b269a0..4edc8e5f 100644 --- a/include/iprt/cpp/utils.h +++ b/include/iprt/cpp/utils.h @@ -96,6 +96,40 @@ inline C *unconst(const C *that) return const_cast(that); } + +/** + * Macro for generating a non-const getter version from a const getter. + * + * @param a_RetType The getter return type. + * @param a_Class The class name. + * @param a_Getter The getter name. + * @param a_ArgDecls The argument declaration for the getter method. + * @param a_ArgList The argument list for the call. + */ +#define RT_CPP_GETTER_UNCONST(a_RetType, a_Class, a_Getter, a_ArgDecls, a_ArgList) \ + a_RetType a_Getter a_ArgDecls \ + { \ + return static_cast< a_Class const *>(this)-> a_Getter a_ArgList; \ + } + + +/** + * Macro for generating a non-const getter version from a const getter, + * unconsting the return value as well. + * + * @param a_RetType The getter return type. + * @param a_Class The class name. + * @param a_Getter The getter name. + * @param a_ArgDecls The argument declaration for the getter method. + * @param a_ArgList The argument list for the call. + */ +#define RT_CPP_GETTER_UNCONST_RET(a_RetType, a_Class, a_Getter, a_ArgDecls, a_ArgList) \ + a_RetType a_Getter a_ArgDecls \ + { \ + return const_cast(static_cast< a_Class const *>(this)-> a_Getter a_ArgList); \ + } + + /** @} */ #endif diff --git a/include/iprt/cpp/xml.h b/include/iprt/cpp/xml.h index bb9f5a18..d45ce746 100644 --- a/include/iprt/cpp/xml.h +++ b/include/iprt/cpp/xml.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2011 Oracle Corporation + * Copyright (C) 2007-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; @@ -30,10 +30,13 @@ # error "There are no XML APIs available in Ring-0 Context!" #endif +#include +#include +#include + #include #include -#include /** @defgroup grp_rt_cpp_xml C++ XML support * @ingroup grp_rt_cpp @@ -380,60 +383,158 @@ class AttributeNode; class ContentNode; /** - * Node base class. Cannot be used directly, but ElementNode, ContentNode and - * AttributeNode derive from this. This does implement useful public methods though. + * Node base class. + * + * Cannot be used directly, but ElementNode, ContentNode and AttributeNode + * derive from this. This does implement useful public methods though. + * + * */ class RT_DECL_CLASS Node { public: - ~Node(); + virtual ~Node(); - const char* getName() const; - bool nameEquals(const char *pcszNamespace, const char *pcsz) const; + const char *getName() const; + const char *getPrefix() const; + const char *getNamespaceURI() const; + bool nameEqualsNS(const char *pcszNamespace, const char *pcsz) const; bool nameEquals(const char *pcsz) const { - return nameEquals(NULL, pcsz); + return nameEqualsNS(NULL, pcsz); } + bool nameEqualsN(const char *pcsz, size_t cchMax, const char *pcszNamespace = NULL) const; - const char* getValue() const; + const char *getValue() const; bool copyValue(int32_t &i) const; bool copyValue(uint32_t &i) const; bool copyValue(int64_t &i) const; bool copyValue(uint64_t &i) const; - int getLineNumber() const; + /** @name Introspection. + * @{ */ + /** Is this an ElementNode instance. + * @returns true / false */ + bool isElement() const + { + return m_Type == IsElement; + } - int isElement() const + /** Is this an ContentNode instance. + * @returns true / false */ + bool isContent() const + { + return m_Type == IsContent; + } + + /** Is this an AttributeNode instance. + * @returns true / false */ + bool isAttribute() const { return m_Type == IsElement; } + int getLineNumber() const; + /** @} */ + + /** @name General tree enumeration. + * + * Use the introspection methods isElement() and isContent() before doing static + * casting. Parents are always or ElementNode type, but siblings and children + * can be of both ContentNode and ElementNode types. + * + * @remarks Attribute node are in the attributes list, while both content and + * element nodes are in the list of children. See ElementNode. + * + * @remarks Careful mixing tree walking with node removal! + * @{ + */ + /** Get the parent node + * @returns Pointer to the parent node, or NULL if root. */ + const Node *getParent() const + { + return m_pParent; + } + + /** Get the previous sibling. + * @returns Pointer to the previous sibling node, NULL if first child. + */ + const Node *getPrevSibiling() const + { + if (!m_pParentListAnchor) + return NULL; + return RTListGetPrevCpp(m_pParentListAnchor, this, const Node, m_listEntry); + } + + /** Get the next sibling. + * @returns Pointer to the next sibling node, NULL if last child. */ + const Node *getNextSibiling() const + { + if (!m_pParentListAnchor) + return NULL; + return RTListGetNextCpp(m_pParentListAnchor, this, const Node, m_listEntry); + } + /** @} */ + protected: - typedef enum {IsElement, IsAttribute, IsContent} EnumType; + /** Node types. */ + typedef enum { IsElement, IsAttribute, IsContent } EnumType; + /** The type of node this is an instance of. */ EnumType m_Type; - Node *m_pParent; - xmlNode *m_plibNode; // != NULL if this is an element or content node - xmlAttr *m_plibAttr; // != NULL if this is an attribute node - const char *m_pcszNamespacePrefix; // not always set - const char *m_pcszNamespaceHref; // full http:// spec - const char *m_pcszName; // element or attribute name, points either into plibNode or plibAttr; - // NULL if this is a content node + /** The parent node (always an element), NULL if root. */ + Node *m_pParent; + + xmlNode *m_pLibNode; ///< != NULL if this is an element or content node + xmlAttr *m_pLibAttr; ///< != NULL if this is an attribute node + const char *m_pcszNamespacePrefix; ///< not always set + const char *m_pcszNamespaceHref; ///< full http:// spec + const char *m_pcszName; ///< element or attribute name, points either into pLibNode or pLibAttr; + ///< NULL if this is a content node + + /** Child list entry of this node. (List head m_pParent->m_children.) */ + RTLISTNODE m_listEntry; + /** Pointer to the parent list anchor. + * This allows us to use m_listEntry both for children and attributes. */ + PRTLISTANCHOR m_pParentListAnchor; // hide the default constructor so people use only our factory methods Node(EnumType type, Node *pParent, - xmlNode *plibNode, - xmlAttr *plibAttr); + PRTLISTANCHOR pListAnchor, + xmlNode *pLibNode, + xmlAttr *pLibAttr); Node(const Node &x); // no copying - void buildChildren(const ElementNode &elmRoot); + friend class AttributeNode; + friend class ElementNode; /* C list hack. */ +}; - /* Obscure class data */ - struct Data; - Data *m; +/** + * Node subclass that represents an attribute of an element. + * + * For attributes, Node::getName() returns the attribute name, and Node::getValue() + * returns the attribute value, if any. + * + * Since the Node constructor is private, one can create new attribute nodes + * only through the following factory methods: + * + * -- ElementNode::setAttribute() + */ +class RT_DECL_CLASS AttributeNode : public Node +{ +public: - friend class AttributeNode; +protected: + // hide the default constructor so people use only our factory methods + AttributeNode(const ElementNode *pElmRoot, + Node *pParent, + PRTLISTANCHOR pListAnchor, + xmlAttr *pLibAttr); + AttributeNode(const AttributeNode &x); // no copying + + friend class Node; + friend class ElementNode; }; /** @@ -451,54 +552,313 @@ protected: class RT_DECL_CLASS ElementNode : public Node { public: - int getChildElements(ElementNodesList &children, - const char *pcszMatch = NULL) const; + int getChildElements(ElementNodesList &children, const char *pcszMatch = NULL) const; - const ElementNode* findChildElement(const char *pcszNamespace, - const char *pcszMatch) const; - const ElementNode* findChildElement(const char *pcszMatch) const + const ElementNode *findChildElementNS(const char *pcszNamespace, const char *pcszMatch) const; + const ElementNode *findChildElement(const char *pcszMatch) const { - return findChildElement(NULL, pcszMatch); + return findChildElementNS(NULL, pcszMatch); } - const ElementNode* findChildElementFromId(const char *pcszId) const; - - const AttributeNode* findAttribute(const char *pcszMatch) const; - bool getAttributeValue(const char *pcszMatch, const char *&ppcsz) const; - bool getAttributeValue(const char *pcszMatch, RTCString &str) const; - bool getAttributeValuePath(const char *pcszMatch, RTCString &str) const; - bool getAttributeValue(const char *pcszMatch, int32_t &i) const; - bool getAttributeValue(const char *pcszMatch, uint32_t &i) const; - bool getAttributeValue(const char *pcszMatch, int64_t &i) const; - bool getAttributeValue(const char *pcszMatch, uint64_t &i) const; - bool getAttributeValue(const char *pcszMatch, bool &f) const; - - ElementNode* createChild(const char *pcszElementName); - - ContentNode* addContent(const char *pcszContent); - ContentNode* addContent(const RTCString &strContent) + const ElementNode *findChildElementFromId(const char *pcszId) const; + + /** Finds the first decendant matching the name at the end of @a pcszPath and + * optionally namespace. + * + * @returns Pointer to the child string value, NULL if not found or no value. + * @param pcszPath The attribute name. Slashes can be used to make a + * simple path to any decendant. + * @param pcszNamespace The namespace to match, NULL (default) match any + * namespace. When using a path, this matches all + * elements along the way. + * @see findChildElement, findChildElementP + */ + const ElementNode *findChildElementP(const char *pcszPath, const char *pcszNamespace = NULL) const; + + /** Finds the first child with matching the give name and optionally namspace, + * returning its value. + * + * @returns Pointer to the child string value, NULL if not found or no value. + * @param pcszPath The attribute name. Slashes can be used to make a + * simple path to any decendant. + * @param pcszNamespace The namespace to match, NULL (default) match any + * namespace. When using a path, this matches all + * elements along the way. + * @see findChildElement, findChildElementP + */ + const char *findChildElementValueP(const char *pcszPath, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + if (pElem) + return pElem->getValue(); + return NULL; + } + + /** Combines findChildElementP and findAttributeValue. + * + * @returns Pointer to attribute string value, NULL if either the element or + * the attribute was not found. + * @param pcszPath The attribute name. Slashes can be used to make a + * simple path to any decendant. + * @param pcszAttribute The attribute name. + * @param pcszPathNamespace The namespace to match @pcszPath with, NULL + * (default) match any namespace. When using a + * path, this matches all elements along the way. + * @param pcszAttribNamespace The namespace prefix to apply to the attribute, + * NULL (default) match any namespace. + * @see findChildElementP and findAttributeValue + */ + const char *findChildElementAttributeValueP(const char *pcszPath, const char *pcszAttribute, + const char *pcszPathNamespace = NULL, + const char *pcszAttributeNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszPathNamespace); + if (pElem) + return pElem->findAttributeValue(pcszAttribute, pcszAttributeNamespace); + return NULL; + } + + + /** @name Tree enumeration. + * @{ */ + + /** Get the next tree element in a full tree enumeration. + * + * By starting with the root node, this can be used to enumerate the entire tree + * (or sub-tree if @a pElmRoot is used). + * + * @returns Pointer to the next element in the tree, NULL if we're done. + * @param pElmRoot The root of the tree we're enumerating. NULL if + * it's the entire tree. + */ + ElementNode const *getNextTreeElement(ElementNode const *pElmRoot = NULL) const; + RT_CPP_GETTER_UNCONST_RET(ElementNode *, ElementNode, getNextTreeElement, (const ElementNode *pElmRoot = NULL), (pElmRoot)) + + /** Get the first child node. + * @returns Pointer to the first child node, NULL if no children. */ + const Node *getFirstChild() const + { + return RTListGetFirstCpp(&m_children, const Node, m_listEntry); + } + RT_CPP_GETTER_UNCONST_RET(Node *, ElementNode, getFirstChild,(),()) + + /** Get the last child node. + * @returns Pointer to the last child node, NULL if no children. */ + const Node *getLastChild() const + { + return RTListGetLastCpp(&m_children, const Node, m_listEntry); + } + + /** Get the first child node. + * @returns Pointer to the first child node, NULL if no children. */ + const ElementNode *getFirstChildElement() const; + + /** Get the last child node. + * @returns Pointer to the last child node, NULL if no children. */ + const ElementNode *getLastChildElement() const; + + /** Get the previous sibling element. + * @returns Pointer to the previous sibling element, NULL if first child + * element. + * @see getNextSibilingElement, getPrevSibling + */ + const ElementNode *getPrevSibilingElement() const; + + /** Get the next sibling element. + * @returns Pointer to the next sibling element, NULL if last child element. + * @see getPrevSibilingElement, getNextSibling + */ + const ElementNode *getNextSibilingElement() const; + + /** Find the previous element matching the given name and namespace (optionally). + * @returns Pointer to the previous sibling element, NULL if first child + * element. + * @param pcszName The element name to match. + * @param pcszNamespace The namespace name, default is NULL which means + * anything goes. + * @note Changed the order of the arguments. + */ + const ElementNode *findPrevSibilingElement(const char *pcszName, const char *pcszNamespace = NULL) const; + + /** Find the next element matching the given name and namespace (optionally). + * @returns Pointer to the previous sibling element, NULL if first child + * element. + * @param pcszName The element name to match. + * @param pcszNamespace The namespace name, default is NULL which means + * anything goes. + * @note Changed the order of the arguments. + */ + const ElementNode *findNextSibilingElement(const char *pcszName, const char *pcszNamespace = NULL) const; + /** @} */ + + + const AttributeNode *findAttribute(const char *pcszMatch, const char *pcszNamespace = NULL) const; + /** Find the first attribute with the given name, returning its value string. + * @returns Pointer to the attribute string value. + * @param pcszName The attribute name. + * @param pcszNamespace The namespace name, default is NULL which means + * anything goes. + * @see getAttributeValue + */ + const char *findAttributeValue(const char *pcszName, const char *pcszNamespace = NULL) const + { + const AttributeNode *pAttr = findAttribute(pcszName, pcszNamespace); + if (pAttr) + return pAttr->getValue(); + return NULL; + } + + bool getAttributeValue(const char *pcszMatch, const char *&pcsz, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &pcsz, pcszNamespace); } + bool getAttributeValue(const char *pcszMatch, RTCString &str, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &str, pcszNamespace); } + bool getAttributeValuePath(const char *pcszMatch, RTCString &str, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &str, pcszNamespace); } + bool getAttributeValue(const char *pcszMatch, int32_t &i, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &i, pcszNamespace); } + bool getAttributeValue(const char *pcszMatch, uint32_t &i, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &i, pcszNamespace); } + bool getAttributeValue(const char *pcszMatch, int64_t &i, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &i, pcszNamespace); } + bool getAttributeValue(const char *pcszMatch, uint64_t &u, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &u, pcszNamespace); } + bool getAttributeValue(const char *pcszMatch, bool &f, const char *pcszNamespace = NULL) const + { return getAttributeValue(pcszMatch, &f, pcszNamespace); } + + /** @name Variants that for clarity does not use references for output params. + * @{ */ + bool getAttributeValue(const char *pcszMatch, const char **ppcsz, const char *pcszNamespace = NULL) const; + bool getAttributeValue(const char *pcszMatch, RTCString *pStr, const char *pcszNamespace = NULL) const; + bool getAttributeValuePath(const char *pcszMatch, RTCString *pStr, const char *pcszNamespace = NULL) const; + bool getAttributeValue(const char *pcszMatch, int32_t *pi, const char *pcszNamespace = NULL) const; + bool getAttributeValue(const char *pcszMatch, uint32_t *pu, const char *pcszNamespace = NULL) const; + bool getAttributeValue(const char *pcszMatch, int64_t *piValue, const char *pcszNamespace = NULL) const; + bool getAttributeValue(const char *pcszMatch, uint64_t *pu, const char *pcszNamespace = NULL) const; + bool getAttributeValue(const char *pcszMatch, bool *pf, const char *pcszNamespace = NULL) const; + /** @} */ + + /** @name Convenience methods for convering the element value. + * @{ */ + bool getElementValue(int32_t *piValue) const; + bool getElementValue(uint32_t *puValue) const; + bool getElementValue(int64_t *piValue) const; + bool getElementValue(uint64_t *puValue) const; + bool getElementValue(bool *pfValue) const; + /** @} */ + + /** @name Convenience findChildElementAttributeValueP and getElementValue. + * @{ */ + bool getChildElementValueP(const char *pcszPath, int32_t *piValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + return pElem && pElem->getElementValue(piValue); + } + bool getChildElementValueP(const char *pcszPath, uint32_t *puValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + return pElem && pElem->getElementValue(puValue); + } + bool getChildElementValueP(const char *pcszPath, int64_t *piValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + return pElem && pElem->getElementValue(piValue); + } + bool getChildElementValueP(const char *pcszPath, uint64_t *puValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + return pElem && pElem->getElementValue(puValue); + } + bool getChildElementValueP(const char *pcszPath, bool *pfValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + return pElem && pElem->getElementValue(pfValue); + } + + /** @} */ + + /** @name Convenience findChildElementAttributeValueP and getElementValue with a + * default value being return if the child element isn't present. + * + * @remarks These will return false on conversion errors. + * @{ */ + bool getChildElementValueDefP(const char *pcszPath, int32_t iDefault, int32_t *piValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + if (pElem) + return pElem->getElementValue(piValue); + *piValue = iDefault; + return true; + } + bool getChildElementValueDefP(const char *pcszPath, uint32_t uDefault, uint32_t *puValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + if (pElem) + return pElem->getElementValue(puValue); + *puValue = uDefault; + return true; + } + bool getChildElementValueDefP(const char *pcszPath, int64_t iDefault, int64_t *piValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + if (pElem) + return pElem->getElementValue(piValue); + *piValue = iDefault; + return true; + } + bool getChildElementValueDefP(const char *pcszPath, uint64_t uDefault, uint64_t *puValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + if (pElem) + return pElem->getElementValue(puValue); + *puValue = uDefault; + return true; + } + bool getChildElementValueDefP(const char *pcszPath, bool fDefault, bool *pfValue, const char *pcszNamespace = NULL) const + { + const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); + if (pElem) + return pElem->getElementValue(pfValue); + *pfValue = fDefault; + return true; + } + /** @} */ + + ElementNode *createChild(const char *pcszElementName); + + ContentNode *addContent(const char *pcszContent); + ContentNode *addContent(const RTCString &strContent) { return addContent(strContent.c_str()); } - AttributeNode* setAttribute(const char *pcszName, const char *pcszValue); - AttributeNode* setAttribute(const char *pcszName, const RTCString &strValue) + AttributeNode *setAttribute(const char *pcszName, const char *pcszValue); + AttributeNode *setAttribute(const char *pcszName, const RTCString &strValue) { return setAttribute(pcszName, strValue.c_str()); } - AttributeNode* setAttributePath(const char *pcszName, const RTCString &strValue); - AttributeNode* setAttribute(const char *pcszName, int32_t i); - AttributeNode* setAttribute(const char *pcszName, uint32_t i); - AttributeNode* setAttribute(const char *pcszName, int64_t i); - AttributeNode* setAttribute(const char *pcszName, uint64_t i); - AttributeNode* setAttributeHex(const char *pcszName, uint32_t i); - AttributeNode* setAttribute(const char *pcszName, bool f); + AttributeNode *setAttributePath(const char *pcszName, const RTCString &strValue); + AttributeNode *setAttribute(const char *pcszName, int32_t i); + AttributeNode *setAttribute(const char *pcszName, uint32_t i); + AttributeNode *setAttribute(const char *pcszName, int64_t i); + AttributeNode *setAttribute(const char *pcszName, uint64_t i); + AttributeNode *setAttributeHex(const char *pcszName, uint32_t i); + AttributeNode *setAttribute(const char *pcszName, bool f); + + virtual ~ElementNode(); protected: // hide the default constructor so people use only our factory methods - ElementNode(const ElementNode *pelmRoot, Node *pParent, xmlNode *plibNode); + ElementNode(const ElementNode *pElmRoot, Node *pParent, PRTLISTANCHOR pListAnchor, xmlNode *pLibNode); ElementNode(const ElementNode &x); // no copying - const ElementNode *m_pelmRoot; + /** We keep a pointer to the root element for attribute namespace handling. */ + const ElementNode *m_pElmRoot; + + /** List of child elements and content nodes. */ + RTLISTANCHOR m_children; + /** List of attributes nodes. */ + RTLISTANCHOR m_attributes; + + static void buildChildren(ElementNode *pElmRoot); friend class Node; friend class Document; @@ -519,41 +879,13 @@ public: protected: // hide the default constructor so people use only our factory methods - ContentNode(Node *pParent, xmlNode *plibNode); + ContentNode(Node *pParent, PRTLISTANCHOR pListAnchor, xmlNode *pLibNode); ContentNode(const ContentNode &x); // no copying friend class Node; friend class ElementNode; }; -/** - * Node subclass that represents an attribute of an element. - * - * For attributes, Node::getName() returns the attribute name, and Node::getValue() - * returns the attribute value, if any. - * - * Since the Node constructor is private, one can create new attribute nodes - * only through the following factory methods: - * - * -- ElementNode::setAttribute() - */ -class RT_DECL_CLASS AttributeNode : public Node -{ -public: - -protected: - // hide the default constructor so people use only our factory methods - AttributeNode(const ElementNode &elmRoot, - Node *pParent, - xmlAttr *plibAttr, - const char **ppcszKey); - AttributeNode(const AttributeNode &x); // no copying - - RTCString m_strKey; - - friend class Node; - friend class ElementNode; -}; /** * Handy helper class with which one can loop through all or some children @@ -583,7 +915,7 @@ private: Document doc; XmlFileParser parser; parser.read("file.xml", doc); - Element *pelmRoot = doc.getRootElement(); + Element *pElmRoot = doc.getRootElement(); @endcode * * -- XmlMemWriter or XmlFileWriter to write out an XML document after it has @@ -591,7 +923,7 @@ private: * * @code Document doc; - Element *pelmRoot = doc.createRootElement(); + Element *pElmRoot = doc.createRootElement(); // add children xml::XmlFileWriter writer(doc); writer.write("file.xml", true); diff --git a/include/iprt/crc.h b/include/iprt/crc.h index 82e3b11b..0f9fa964 100644 --- a/include/iprt/crc.h +++ b/include/iprt/crc.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2009 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/include/iprt/critsect.h b/include/iprt/critsect.h index 41bb65bd..9dee8612 100644 --- a/include/iprt/critsect.h +++ b/include/iprt/critsect.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 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; @@ -109,6 +109,7 @@ AssertCompileSize(RTCRITSECT, HC_ARCH_BITS == 32 ? 32 : 48); #define RTCRITSECT_FLAGS_NOP UINT32_C(0x00000008) /** @} */ + #ifdef IN_RING3 /** @@ -120,18 +121,17 @@ RTDECL(int) RTCritSectInit(PRTCRITSECT pCritSect); * Initialize a critical section. * * @returns iprt status code. - * @param pCritSect Pointer to the critical section structure. - * @param fFlags Flags, any combination of the RTCRITSECT_FLAGS - * \#defines. - * @param hClass The class (no reference consumed). If NIL, no - * lock order validation will be performed on this - * lock. - * @param uSubClass The sub-class. This is used to define lock - * order within a class. RTLOCKVAL_SUB_CLASS_NONE - * is the recommended value here. - * @param pszNameFmt Name format string for the lock validator, - * optional (NULL). Max length is 32 bytes. - * @param ... Format string arguments. + * @param pCritSect Pointer to the critical section structure. + * @param fFlags Flags, any combination of the RTCRITSECT_FLAGS + * \#defines. + * @param hClass The class (no reference consumed). If NIL, no lock + * order validation will be performed on this lock. + * @param uSubClass The sub-class. This is used to define lock order + * within a class. RTLOCKVAL_SUB_CLASS_NONE is the + * recommended value here. + * @param pszNameFmt Name format string for the lock validator, optional + * (NULL). Max length is 32 bytes. + * @param ... Format string arguments. */ RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags, RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...); @@ -145,8 +145,8 @@ RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags, * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the * lock validator isn't compiled in or either of the parameters are * invalid. - * @param pCritSect The critical section. - * @param uSubClass The new sub-class value. + * @param pCritSect The critical section. + * @param uSubClass The new sub-class value. */ RTDECL(uint32_t) RTCritSectSetSubClass(PRTCRITSECT pCritSect, uint32_t uSubClass); @@ -155,7 +155,8 @@ RTDECL(uint32_t) RTCritSectSetSubClass(PRTCRITSECT pCritSect, uint32_t uSubClass * * @returns VINF_SUCCESS on success. * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) - * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. * @param pCritSect The critical section. */ RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect); @@ -163,9 +164,11 @@ RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect); /** * Enter a critical section. * + * @returns IPRT status code. * @retval VINF_SUCCESS on success. * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) - * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. * * @param pCritSect The critical section. * @param uId Where we're entering the section. @@ -181,7 +184,8 @@ RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_ * @retval VINF_SUCCESS on success. * @retval VERR_SEM_BUSY if the critsect was owned. * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) - * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. * * @param pCritSect The critical section. */ @@ -193,7 +197,8 @@ RTDECL(int) RTCritSectTryEnter(PRTCRITSECT pCritSect); * @retval VINF_SUCCESS on success. * @retval VERR_SEM_BUSY if the critsect was owned. * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) - * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. * * @param pCritSect The critical section. * @param uId Where we're entering the section. @@ -210,7 +215,8 @@ RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_S * * @returns VINF_SUCCESS on success. * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) - * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. * @param cCritSects Number of critical sections in the array. * @param papCritSects Array of critical section pointers. * @@ -227,7 +233,8 @@ RTDECL(int) RTCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects * * @returns VINF_SUCCESS on success. * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) - * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. * * @param cCritSects Number of critical sections in the array. * @param papCritSects Array of critical section pointers. @@ -244,7 +251,7 @@ RTDECL(int) RTCritSectEnterMultipleDebug(size_t cCritSects, PRTCRITSECT *papCrit * Leave a critical section. * * @returns VINF_SUCCESS. - * @param pCritSect The critical section. + * @param pCritSect The critical section. */ RTDECL(int) RTCritSectLeave(PRTCRITSECT pCritSect); @@ -261,7 +268,7 @@ RTDECL(int) RTCritSectLeaveMultiple(size_t cCritSects, PRTCRITSECT *papCritSects * Deletes a critical section. * * @returns VINF_SUCCESS. - * @param pCritSect The critical section. + * @param pCritSect The critical section. */ RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect); @@ -270,7 +277,7 @@ RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect); * * @returns true if owner. * @returns false if not owner. - * @param pCritSect The critical section. + * @param pCritSect The critical section. */ DECLINLINE(bool) RTCritSectIsOwner(PCRTCRITSECT pCritSect) { @@ -284,7 +291,7 @@ DECLINLINE(bool) RTCritSectIsOwner(PCRTCRITSECT pCritSect) * * @returns true if owned. * @returns false if not owned. - * @param pCritSect The critical section. + * @param pCritSect The critical section. */ DECLINLINE(bool) RTCritSectIsOwned(PCRTCRITSECT pCritSect) { @@ -296,7 +303,7 @@ DECLINLINE(bool) RTCritSectIsOwned(PCRTCRITSECT pCritSect) * * @returns Thread id of the owner thread if owned. * @returns NIL_RTNATIVETHREAD is not owned. - * @param pCritSect The critical section. + * @param pCritSect The critical section. */ DECLINLINE(RTNATIVETHREAD) RTCritSectGetOwner(PCRTCRITSECT pCritSect) { @@ -308,7 +315,7 @@ DECLINLINE(RTNATIVETHREAD) RTCritSectGetOwner(PCRTCRITSECT pCritSect) * * @returns true if initialized. * @returns false if not initialized. - * @param pCritSect The critical section. + * @param pCritSect The critical section. */ DECLINLINE(bool) RTCritSectIsInitialized(PCRTCRITSECT pCritSect) { @@ -351,13 +358,385 @@ DECLINLINE(int32_t) RTCritSectGetWaiters(PCRTCRITSECT pCritSect) #endif /* Strict lock order: Automatically classify locks by init location. */ -#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTCRITSECT_WITHOUT_REMAPPING) &&!defined(RT_WITH_MANGLING) +#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTCRITSECT_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING) # define RTCritSectInit(pCritSect) \ RTCritSectInitEx((pCritSect), 0 /*fFlags*/, \ RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \ RTLOCKVAL_SUB_CLASS_NONE, NULL) #endif +/** @} */ + + + +/** @defgroup grp_rt_critsectrw RTCritSectRw - Read/Write Critical Sections + * @ingroup grp_rt + * @{ + */ + +/** + * Read/write critical section. + */ +typedef struct RTCRITSECTRW +{ + /** Magic used to validate the section state. + * RTCRITSECTRW_MAGIC is the value of an initialized & operational section. */ + volatile uint32_t u32Magic; + + /** Indicates whether hEvtRead needs resetting. */ + bool volatile fNeedReset; + /** Explicit alignment padding. */ + bool volatile afPadding[1]; + /** Section flags - the RTCRITSECT_FLAGS_* \#defines. */ + uint16_t fFlags; + + /** The state variable. + * All accesses are atomic and it bits are defined like this: + * Bits 0..14 - cReads. + * Bit 15 - Unused. + * Bits 16..31 - cWrites. - doesn't make sense here + * Bit 31 - fDirection; 0=Read, 1=Write. + * Bits 32..46 - cWaitingReads + * Bit 47 - Unused. + * Bits 48..62 - cWaitingWrites + * Bit 63 - Unused. + */ + uint64_t volatile u64State; + /** The write owner. */ + RTNATIVETHREAD volatile hNativeWriter; + /** The number of reads made by the current writer. */ + uint32_t volatile cWriterReads; + /** The number of recursions made by the current writer. (The initial grabbing + * of the lock counts as the first one.) */ + uint32_t volatile cWriteRecursions; + + /** What the writer threads are blocking on. */ + RTSEMEVENT hEvtWrite; + /** What the read threads are blocking on when waiting for the writer to + * finish. */ + RTSEMEVENTMULTI hEvtRead; + + /** The validator record for the writer. */ + R3R0PTRTYPE(PRTLOCKVALRECEXCL) pValidatorWrite; + /** The validator record for the readers. */ + R3R0PTRTYPE(PRTLOCKVALRECSHRD) pValidatorRead; +#if HC_ARCH_BITS == 32 + /** Size padding. */ + RTHCPTR HCPtrPadding; +#endif +} RTCRITSECTRW; +AssertCompileSize(RTCRITSECTRW, HC_ARCH_BITS == 32 ? 48 : 64); + +/** RTCRITSECTRW::u32Magic value. (Eric Allan Dolphy, Jr.) */ +#define RTCRITSECTRW_MAGIC UINT32_C(0x19280620) +/** RTCRITSECTRW::u32Magic dead value. */ +#define RTCRITSECTRW_MAGIC_DEAD UINT32_C(0x19640629) + +/** @name RTCRITSECTRW::u64State values. + * @note Using RTCSRW instead of RTCRITSECTRW to save space. + * @{ */ +#define RTCSRW_CNT_BITS 15 +#define RTCSRW_CNT_MASK UINT64_C(0x00007fff) + +#define RTCSRW_CNT_RD_SHIFT 0 +#define RTCSRW_CNT_RD_MASK (RTCSRW_CNT_MASK << RTCSRW_CNT_RD_SHIFT) +#define RTCSRW_CNT_WR_SHIFT 16 +#define RTCSRW_CNT_WR_MASK (RTCSRW_CNT_MASK << RTCSRW_CNT_WR_SHIFT) + +#define RTCSRW_DIR_SHIFT 31 +#define RTCSRW_DIR_MASK RT_BIT_64(RTCSRW_DIR_SHIFT) +#define RTCSRW_DIR_READ UINT64_C(0) +#define RTCSRW_DIR_WRITE UINT64_C(1) + +#define RTCSRW_WAIT_CNT_RD_SHIFT 32 +#define RTCSRW_WAIT_CNT_RD_MASK (RTCSRW_CNT_MASK << RTCSRW_WAIT_CNT_RD_SHIFT) +/* #define RTCSRW_WAIT_CNT_WR_SHIFT 48 */ +/* #define RTCSRW_WAIT_CNT_WR_MASK (RTCSRW_CNT_MASK << RTCSRW_WAIT_CNT_WR_SHIFT) */ +/** @} */ + +#ifdef IN_RING3 + +/** + * Initialize a critical section. + */ +RTDECL(int) RTCritSectRwInit(PRTCRITSECTRW pThis); + +/** + * Initialize a critical section. + * + * @returns IPRT status code. + * @param pThis Pointer to the read/write critical section. + * @param fFlags Flags, any combination of the RTCRITSECT_FLAGS + * \#defines. + * @param hClass The class (no reference consumed). If NIL, no lock + * order validation will be performed on this lock. + * @param uSubClass The sub-class. This is used to define lock order + * within a class. RTLOCKVAL_SUB_CLASS_NONE is the + * recommended value here. + * @param pszNameFmt Name format string for the lock validator, optional + * (NULL). Max length is 32 bytes. + * @param ... Format string arguments. + */ +RTDECL(int) RTCritSectRwInitEx(PRTCRITSECTRW pThis, uint32_t fFlags, + RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...); + +/** + * Changes the lock validator sub-class of the critical section. + * + * It is recommended to try make sure that nobody is using this critical section + * while changing the value. + * + * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the + * lock validator isn't compiled in or either of the parameters are + * invalid. + * @param pThis Pointer to the read/write critical section. + * @param uSubClass The new sub-class value. + */ +RTDECL(uint32_t) RTCritSectRwSetSubClass(PRTCRITSECTRW pThis, uint32_t uSubClass); + + +/** + * Enter a critical section with shared (read) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwEnterShared(PRTCRITSECTRW pThis); + +/** + * Enter a critical section with shared (read) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * + * @param pThis Pointer to the read/write critical section. + * @param uId Where we're entering the section. + * @param pszFile The source position - file. + * @param iLine The source position - line. + * @param pszFunction The source position - function. + */ +RTDECL(int) RTCritSectRwEnterSharedDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL); + +/** + * Try enter a critical section with shared (read) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_BUSY if the critsect was owned. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwTryEnterShared(PRTCRITSECTRW pThis); + +/** + * Try enter a critical section with shared (read) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_BUSY if the critsect was owned. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * + * @param pThis Pointer to the read/write critical section. + * @param uId Where we're entering the section. + * @param pszFile The source position - file. + * @param iLine The source position - line. + * @param pszFunction The source position - function. + */ +RTDECL(int) RTCritSectRwTryEnterSharedDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL); + +/** + * Leave a critical section held with shared access. + * + * @returns IPRT status code. + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwLeaveShared(PRTCRITSECTRW pThis); + + +/** + * Enter a critical section with exclusive (write) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwEnterExcl(PRTCRITSECTRW pThis); + +/** + * Enter a critical section with exclusive (write) access. + * + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * + * @param pThis Pointer to the read/write critical section. + * @param uId Where we're entering the section. + * @param pszFile The source position - file. + * @param iLine The source position - line. + * @param pszFunction The source position - function. + */ +RTDECL(int) RTCritSectRwEnterExclDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL); + +/** + * Try enter a critical section with exclusive (write) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_BUSY if the critsect was owned. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwTryEnterExcl(PRTCRITSECTRW pThis); + +/** + * Try enter a critical section with exclusive (write) access. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_SEM_BUSY if the critsect was owned. + * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) + * @retval VERR_SEM_DESTROYED if the critical section is delete before or + * during the operation. + * + * @param pThis Pointer to the read/write critical section. + * @param uId Where we're entering the section. + * @param pszFile The source position - file. + * @param iLine The source position - line. + * @param pszFunction The source position - function. + */ +RTDECL(int) RTCritSectRwTryEnterExclDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL); + +/** + * Leave a critical section held exclusively. + * + * @returns IPRT status code; VINF_SUCCESS, VERR_NOT_OWNER, VERR_SEM_DESTROYED, + * or VERR_WRONG_ORDER. + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwLeaveExcl(PRTCRITSECTRW pThis); + + +/** + * Deletes a critical section. + * + * @returns VINF_SUCCESS. + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(int) RTCritSectRwDelete(PRTCRITSECTRW pThis); + +/** + * Checks the caller is the exclusive (write) owner of the critical section. + * + * @retval @c true if owner. + * @retval @c false if not owner. + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(bool) RTCritSectRwIsWriteOwner(PRTCRITSECTRW pThis); + +/** + * Checks if the caller is one of the read owners of the critical section. + * + * @note !CAUTION! This API doesn't work reliably if lock validation isn't + * enabled. Meaning, the answer is not trustworhty unless + * RT_LOCK_STRICT or RTCRITSECTRW_STRICT was defined at build time. + * Also, make sure you do not use RTCRITSECTRW_FLAGS_NO_LOCK_VAL when + * creating the semaphore. And finally, if you used a locking class, + * don't disable deadlock detection by setting cMsMinDeadlock to + * RT_INDEFINITE_WAIT. + * + * In short, only use this for assertions. + * + * @returns @c true if reader, @c false if not. + * @param pThis Pointer to the read/write critical section. + * @param fWannaHear What you'd like to hear when lock validation is not + * available. (For avoiding asserting all over the + * place.) + */ +RTDECL(bool) RTCritSectRwIsReadOwner(PRTCRITSECTRW pThis, bool fWannaHear); + +/** + * Gets the write recursion count. + * + * @returns The write recursion count (0 if bad critsect). + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(uint32_t) RTCritSectRwGetWriteRecursion(PRTCRITSECTRW pThis); + +/** + * Gets the read recursion count of the current writer. + * + * @returns The read recursion count (0 if bad critsect). + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(uint32_t) RTCritSectRwGetWriterReadRecursion(PRTCRITSECTRW pThis); + +/** + * Gets the current number of reads. + * + * This includes all read recursions, so it might be higher than the number of + * read owners. It does not include reads done by the current writer. + * + * @returns The read count (0 if bad critsect). + * @param pThis Pointer to the read/write critical section. + */ +RTDECL(uint32_t) RTCritSectRwGetReadCount(PRTCRITSECTRW pThis); + +#endif /* IN_RING3 */ + +/** + * Checks if a critical section is initialized or not. + * + * @retval @c true if initialized. + * @retval @c false if not initialized. + * @param pThis Pointer to the read/write critical section. + */ +DECLINLINE(bool) RTCritSectRwIsInitialized(PCRTCRITSECTRW pThis) +{ + return pThis->u32Magic == RTCRITSECTRW_MAGIC; +} + +/* Lock strict build: Remap the three enter calls to the debug versions. */ +#if defined(RT_LOCK_STRICT) && !defined(RTCRITSECTRW_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING) +# ifdef ___iprt_asm_h +# define RTCritSectRwEnterExcl(pThis) RTCritSectRwEnterExclDebug(pThis, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define RTCritSectRwTryEnterExcl(pThis) RTCritSectRwTryEnterExclDebug(pThis, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define RTCritSectRwEnterShared(pThis) RTCritSectRwEnterSharedDebug(pThis, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define RTCritSectRwTryEnterShared(pThis) RTCritSectRwTryEnterSharedDebug(pThis, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# else +# define RTCritSectRwEnterExcl(pThis) RTCritSectRwEnterExclDebug(pThis, 0, RT_SRC_POS) +# define RTCritSectRwTryEnterExcl(pThis) RTCritSectRwTryEnterExclDebug(pThis, 0, RT_SRC_POS) +# define RTCritSectRwEnterShared(pThis) RTCritSectRwEnterSharedDebug(pThis, 0, RT_SRC_POS) +# define RTCritSectRwTryEnterShared(pThis) RTCritSectRwTryEnterSharedDebug(pThis, 0, RT_SRC_POS) +# endif +#endif + +/* Strict lock order: Automatically classify locks by init location. */ +#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTCRITSECTRW_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING) +# define RTCritSectRwInit(a_pThis) \ + RTCritSectRwInitEx((a_pThis), 0 /*fFlags*/, \ + RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \ + RTLOCKVAL_SUB_CLASS_NONE, NULL) +#endif + /** @} */ RT_C_DECLS_END diff --git a/include/iprt/ctype.h b/include/iprt/ctype.h index b491aa32..e97b00d7 100644 --- a/include/iprt/ctype.h +++ b/include/iprt/ctype.h @@ -3,7 +3,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/include/iprt/dbg.h b/include/iprt/dbg.h index 04bea827..4a384a05 100644 --- a/include/iprt/dbg.h +++ b/include/iprt/dbg.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008-2009 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; @@ -29,6 +29,7 @@ #include #include +#include RT_C_DECLS_BEGIN @@ -61,6 +62,7 @@ typedef RTDBGSEGIDX const *PCRTDBGSEGIDX; #define RTDBGSEGIDX_SPECIAL_FIRST (RTDBGSEGIDX_LAST + 1U) + /** @name RTDBGSYMADDR_FLAGS_XXX * Flags used when looking up a symbol by address. * @{ */ @@ -212,6 +214,258 @@ RTDECL(PRTDBGLINE) RTDbgLineDup(PCRTDBGLINE pLine); RTDECL(void) RTDbgLineFree(PRTDBGLINE pLine); +/** @defgroup grp_rt_dbgcfg RTDbgCfg - Debugging Configuration + * + * The settings used when loading and processing debug info is kept in a + * RTDBGCFG instance since it's generally shared for a whole debugging session + * and anyhow would be a major pain to pass as individual parameters to each + * call. The debugging config API not only keeps the settings information but + * also provide APIs for making use of it, and in some cases, like for instance + * symbol severs, retriving and maintaining it. + * + * @todo Work in progress - APIs are still missing, adding when needed. + * + * @{ + */ + +/** Debugging configuration handle. */ +typedef struct RTDBGCFGINT *RTDBGCFG; +/** Pointer to a debugging configuration handle. */ +typedef RTDBGCFG *PRTDBGCFG; +/** NIL debug configuration handle. */ +#define NIL_RTDBGCFG ((RTDBGCFG)0) + +/** @name RTDBGCFG_FLAGS_XXX - Debugging configuration flags. + * @{ */ +/** Use deferred loading. */ +#define RTDBGCFG_FLAGS_DEFERRED RT_BIT_64(0) +/** Don't use the symbol server (http). */ +#define RTDBGCFG_FLAGS_NO_SYM_SRV RT_BIT_64(1) +/** Don't use system search paths. + * On windows this means not using _NT_ALT_SYMBOL_PATH, _NT_SYMBOL_PATH, + * _NT_SOURCE_PATH, and _NT_EXECUTABLE_PATH. + * On other systems the effect has yet to be determined. */ +#define RTDBGCFG_FLAGS_NO_SYSTEM_PATHS RT_BIT_64(2) +/** Don't search the debug and image paths recursively. */ +#define RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH RT_BIT_64(3) +/** Don't search the source paths recursively. */ +#define RTDBGCFG_FLAGS_NO_RECURSIV_SRC_SEARCH RT_BIT_64(4) +/** @} */ + +/** + * Debugging configuration properties. + * + * The search paths are using the DOS convention of semicolon as separator + * character. The the special 'srv' + asterisk syntax known from the windows + * debugger search paths are also supported to some extent, as is 'cache' + + * asterisk. + */ +typedef enum RTDBGCFGPROP +{ + /** The customary invalid 0 value. */ + RTDBGCFGPROP_INVALID = 0, + /** RTDBGCFG_FLAGS_XXX. + * Env: _FLAGS + * The environment variable can be specified as a unsigned value or one or more + * mnemonics separated by spaces. */ + RTDBGCFGPROP_FLAGS, + /** List of paths to search for symbol files and images. + * Env: _PATH */ + RTDBGCFGPROP_PATH, + /** List of symbol file suffixes (semicolon separated). + * Env: _SUFFIXES */ + RTDBGCFGPROP_SUFFIXES, + /** List of paths to search for source files. + * Env: _SRC_PATH */ + RTDBGCFGPROP_SRC_PATH, + /** End of valid values. */ + RTDBGCFGPROP_END, + /** The customary 32-bit type hack. */ + RTDBGCFGPROP_32BIT_HACK = 0x7fffffff +} RTDBGCFGPROP; + +/** + * Configuration property change operation. + */ +typedef enum RTDBGCFGOP +{ + /** Customary invalid 0 value. */ + RTDBGCFGOP_INVALID = 0, + /** Replace the current value with the given one. */ + RTDBGCFGOP_SET, + /** Append the given value to the existing one. For integer values this is + * considered a bitwise OR operation. */ + RTDBGCFGOP_APPEND, + /** Prepend the given value to the existing one. For integer values this is + * considered a bitwise OR operation. */ + RTDBGCFGOP_PREPEND, + /** Removes the value from the existing one. For interger values the value is + * complemented and ANDed with the existing one, clearing all the specified + * flags/bits. */ + RTDBGCFGOP_REMOVE, + /** End of valid values. */ + RTDBGCFGOP_END, + /** Customary 32-bit type hack. */ + RTDBGCFGOP_32BIT_HACK = 0x7fffffff +} RTDBGCFGOP; + + + +/** + * Initializes a debugging configuration. + * + * @returns IPRT status code. + * @param phDbgCfg Where to return the configuration handle. + * @param pszEnvVarPrefix The environment variable prefix. If NULL, the + * environment is not consulted. + * @param fNativePaths Whether to pick up native paths from the + * environment. + * + * @sa RTDbgCfgChangeString, RTDbgCfgChangeUInt. + */ +RTDECL(int) RTDbgCfgCreate(PRTDBGCFG phDbgCfg, const char *pszEnvVarPrefix, bool fNativePaths); + +/** + * Retains a new reference to a debugging config. + * + * @returns New reference count. + * UINT32_MAX is returned if the handle is invalid (asserted). + * @param hDbgCfg The config handle. + */ +RTDECL(uint32_t) RTDbgCfgRetain(RTDBGCFG hDbgCfg); + +/** + * Releases a references to a debugging config. + * + * @returns New reference count, if 0 the config was freed. UINT32_MAX is + * returned if the handle is invalid (asserted). + * @param hDbgCfg The config handle. + */ +RTDECL(uint32_t) RTDbgCfgRelease(RTDBGCFG hDbgCfg); + +/** + * Changes a property value by string. + * + * For string values the string is used more or less as given. For integer + * values and flags, it can contains both values (ORed together) or property + * specific mnemonics (ORed / ~ANDed). + * + * @returns IPRT status code. + * @retval VERR_DBG_CFG_INVALID_VALUE + * @param hDbgCfg The debugging configuration handle. + * @param enmProp The property to change. + * @param enmOp How to change the property. + * @param pszValue The property value to apply. + */ +RTDECL(int) RTDbgCfgChangeString(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, RTDBGCFGOP enmOp, const char *pszValue); + +/** + * Changes a property value by unsigned integer (64-bit). + * + * This can only be applied to integer and flag properties. + * + * @returns IPRT status code. + * @retval VERR_DBG_CFG_NOT_UINT_PROP + * @param hDbgCfg The debugging configuration handle. + * @param enmProp The property to change. + * @param enmOp How to change the property. + * @param uValue The property value to apply. + */ +RTDECL(int) RTDbgCfgChangeUInt(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, RTDBGCFGOP enmOp, uint64_t uValue); + +/** + * Query a property value as string. + * + * Integer and flags properties are returned as a list of mnemonics if possible, + * otherwise as simple hex values. + * + * @returns IPRT status code. + * @retval VERR_BUFFER_OVERFLOW if there isn't sufficient buffer space. Nothing + * is written. + * @param hDbgCfg The debugging configuration handle. + * @param enmProp The property to change. + * @param pszValue The output buffer. + * @param cbValue The size of the output buffer. + */ +RTDECL(int) RTDbgCfgQueryString(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, char *pszValue, size_t cbValue); + +/** + * Query a property value as unsigned integer (64-bit). + * + * Only integer and flags properties can be queried this way. + * + * @returns IPRT status code. + * @retval VERR_DBG_CFG_NOT_UINT_PROP + * @param hDbgCfg The debugging configuration handle. + * @param enmProp The property to change. + * @param puValue Where to return the value. + */ +RTDECL(int) RTDbgCfgQueryUInt(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, uint64_t *puValue); + +/** + * Log callback. + * + * @param hDbgCfg The debug config instance. + * @param iLevel The message level. + * @param pszMsg The message. + * @param pvUser User argument. + */ +typedef DECLCALLBACK(void) FNRTDBGCFGLOG(RTDBGCFG hDbgCfg, uint32_t iLevel, const char *pszMsg, void *pvUser); +/** Pointer to a log callback. */ +typedef FNRTDBGCFGLOG *PFNRTDBGCFGLOG; + +/** + * Sets the log callback for the configuration. + * + * This will fail if there is already a log callback present, unless pfnCallback + * is NULL. + * + * @returns IPRT status code. + * @param hDbgCfg The debugging configuration handle. + * @param pfnCallback The callback function. NULL to unset. + * @param pvUser The user argument. + */ +RTDECL(int) RTDbgCfgSetLogCallback(RTDBGCFG hDbgCfg, PFNRTDBGCFGLOG pfnCallback, void *pvUser); + +/** + * Callback used by the RTDbgCfgOpen function to try out a file that was found. + * + * @returns On statuses other than VINF_CALLBACK_RETURN and + * VERR_CALLBACK_RETURN the search will continue till the end of the + * list. These status codes will not necessarily be propagated to the + * caller in any consistent manner. + * @retval VINF_CALLBACK_RETURN if successuflly opened the file and it's time + * to return + * @retval VERR_CALLBACK_RETURN if we shouldn't stop searching. + * + * @param hDbgCfg The debugging configuration handle. + * @param pszFilename The path to the file that should be tried out. + * @param pvUser1 First user parameter. + * @param pvUser2 Second user parameter. + */ +typedef DECLCALLBACK(int) FNDBGCFGOPEN(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2); +/** Pointer to a open-file callback used to the RTDbgCfgOpen functions. */ +typedef FNDBGCFGOPEN *PFNDBGCFGOPEN; + + +RTDECL(int) RTDbgCfgOpenPeImage(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, + PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2); +RTDECL(int) RTDbgCfgOpenPdb70(RTDBGCFG hDbgCfg, const char *pszFilename, PCRTUUID pUuid, uint32_t uAge, + PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2); +RTDECL(int) RTDbgCfgOpenPdb20(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, uint32_t uAge, + PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2); +RTDECL(int) RTDbgCfgOpenDbg(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, + PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2); +RTDECL(int) RTDbgCfgOpenDwo(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t uCrc32, + PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2); + +RTDECL(int) RTDbgCfgOpenDsymBundle(RTDBGCFG hDbgCfg, const char *pszFilename, PCRTUUID pUuid, + PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2); + + +/** @} */ + + /** @defgroup grp_rt_dbgas RTDbgAs - Debug Address Space * @{ */ @@ -282,6 +536,22 @@ RTDECL(uint32_t) RTDbgAsRetain(RTDBGAS hDbgAs); */ RTDECL(uint32_t) RTDbgAsRelease(RTDBGAS hDbgAs); +/** + * Locks the address space for exclusive access. + * + * @returns IRPT status code + * @param hDbgAs The address space handle. + */ +RTDECL(int) RTDbgAsLockExcl(RTDBGAS hDbgAs); + +/** + * Counters the actions of one RTDbgAsUnlockExcl call. + * + * @returns IRPT status code + * @param hDbgAs The address space handle. + */ +RTDECL(int) RTDbgAsUnlockExcl(RTDBGAS hDbgAs); + /** * Gets the name of an address space. * @@ -579,25 +849,10 @@ RTDECL(int) RTDbgAsSymbolByName(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYM */ RTDECL(int) RTDbgAsSymbolByNameA(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod); -/** - * Query a line number by address. - * - * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones. - * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. - * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module. - * - * @param hDbgAs The address space handle. - * @param Addr The address which closest symbol is requested. - * @param poffDisp Where to return the distance between the line - * number and address. - * @param pLine Where to return the line number information. - */ -RTDECL(int) RTDbgAs(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine); - /** * Adds a line number to a module in the address space. * - * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones. + * @returns IPRT status code. See RTDbgModLineAdd for more specific ones. * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. * @retval VERR_NOT_FOUND if no module was found at the specified address. * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding @@ -613,11 +868,10 @@ RTDECL(int) RTDbgAs(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLI */ RTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo, RTUINTPTR Addr, uint32_t *piOrdinal); - /** * Query a line number by address. * - * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones. + * @returns IPRT status code. See RTDbgModLineAddrA for more specific ones. * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module. * @@ -626,13 +880,14 @@ RTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo * @param poffDisp Where to return the distance between the line * number and address. * @param pLine Where to return the line number information. + * @param phMod Where to return the module handle. Optional. */ -RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine); +RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod); /** * Query a line number by address. * - * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones. + * @returns IPRT status code. See RTDbgModLineAddrA for more specific ones. * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module. * @@ -642,8 +897,9 @@ RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp * number and address. * @param ppLine Where to return the pointer to the allocated line * number info. Always set. Free with RTDbgLineFree. + * @param phMod Where to return the module handle. Optional. */ -RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine); +RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine, PRTDBGMOD phMod); /** @todo Missing some bits here. */ @@ -672,9 +928,18 @@ RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDis */ RTDECL(int) RTDbgModCreate(PRTDBGMOD phDbgMod, const char *pszName, RTUINTPTR cbSeg, uint32_t fFlags); -RTDECL(int) RTDbgModCreateDeferred(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR cb, uint32_t fFlags); -RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t fFlags); -RTDECL(int) RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR uSubtrahend, uint32_t fFlags); +RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, + RTLDRARCH enmArch, RTDBGCFG hDbgCfg); +RTDECL(int) RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR uSubtrahend, + RTDBGCFG hDbgCfg); +RTDECL(int) RTDbgModCreateFromPeImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTLDRMOD hLdrMod, + uint32_t cbImage, uint32_t uTimeDateStamp, RTDBGCFG hDbgCfg); +RTDECL(int) RTDbgModCreateFromDbg(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t cbImage, + uint32_t uTimeDateStamp, RTDBGCFG hDbgCfg); +RTDECL(int) RTDbgModCreateFromPdb(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t cbImage, + PCRTUUID pUuid, uint32_t Age, RTDBGCFG hDbgCfg); +RTDECL(int) RTDbgModCreateFromDwo(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t cbImage, + uint32_t uCrc32, RTDBGCFG hDbgCfg); /** @@ -702,6 +967,18 @@ RTDECL(uint32_t) RTDbgModRetain(RTDBGMOD hDbgMod); */ RTDECL(uint32_t) RTDbgModRelease(RTDBGMOD hDbgMod); +/** + * Removes all content from the debug module (container), optionally only + * leaving segments and image size intact. + * + * This is only possible on container modules, i.e. created by RTDbgModCreate(). + * + * @returns IPRT status code. + * @param hDbgMod The module handle. + * @param fLeaveSegments Whether to leave segments (and image size) as is. + */ +RTDECL(int) RTDbgModRemoveAll(RTDBGMOD hDbgMod, bool fLeaveSegments); + /** * Gets the module name. * @@ -711,6 +988,51 @@ RTDECL(uint32_t) RTDbgModRelease(RTDBGMOD hDbgMod); */ RTDECL(const char *) RTDbgModName(RTDBGMOD hDbgMod); +/** + * Gets the name of the debug info file we're using. + * + * @returns Pointer to a read only string containing the filename, NULL if we + * don't use one. + * + * @param hDbgMod The module handle. + */ +RTDECL(const char *) RTDbgModDebugFile(RTDBGMOD hDbgMod); + +/** + * Gets the image filename (as specified by the user). + * + * @returns Pointer to a read only string containing the filename. + * + * @param hDbgMod The module handle. + */ +RTDECL(const char *) RTDbgModImageFile(RTDBGMOD hDbgMod); + +/** + * Gets the image filename actually used if it differs from RTDbgModImageFile. + * + * @returns Pointer to a read only string containing the filename, NULL if same + * as RTDBgModImageFile. + * + * @param hDbgMod The module handle. + */ +RTDECL(const char *) RTDbgModImageFileUsed(RTDBGMOD hDbgMod); + +/** + * Checks if the loading of the debug info has been postponed. + * + * @returns true if postponed, false if not or invalid handle. + * @param hDbgMod The module handle. + */ +RTDECL(bool) RTDbgModIsDeferred(RTDBGMOD hDbgMod); + +/** + * Checks if the debug info is exports only. + * + * @returns true if exports only, false if not or invalid handle. + * @param hDbgMod The module handle. + */ +RTDECL(bool) RTDbgModIsExports(RTDBGMOD hDbgMod); + /** * Converts an image relative address to a segment:offset address. * diff --git a/include/iprt/dir.h b/include/iprt/dir.h index 38d99aa3..54e23594 100644 --- a/include/iprt/dir.h +++ b/include/iprt/dir.h @@ -3,7 +3,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; @@ -272,8 +272,8 @@ typedef struct RTDIRENTRY * RTDIRENTRYTYPE_UNKNOWN is a common return value here since not all file * systems (or Unixes) stores the type of a directory entry and instead * expects the user to use stat() to get it. So, when you see this you - * should use RTPathQueryInfo to get the type, or if if you're lazy, use - * RTDirReadEx. */ + * should use RTDirQueryUnknownType or RTDirQueryUnknownTypeEx to get the type, + * or if if you're lazy, use RTDirReadEx. */ RTDIRENTRYTYPE enmType; /** The length of the filename, excluding the terminating nul character. */ uint16_t cbName; @@ -284,6 +284,8 @@ typedef struct RTDIRENTRY #pragma pack() /** Pointer to a directory entry. */ typedef RTDIRENTRY *PRTDIRENTRY; +/** Pointer to a const directory entry. */ +typedef RTDIRENTRY const *PCRTDIRENTRY; /** @@ -313,6 +315,8 @@ typedef struct RTDIRENTRYEX #pragma pack() /** Pointer to a directory entry. */ typedef RTDIRENTRYEX *PRTDIRENTRYEX; +/** Pointer to a const directory entry. */ +typedef RTDIRENTRYEX const *PCRTDIRENTRYEX; /** @@ -409,6 +413,55 @@ RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry); */ RTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags); +/** + * Resolves RTDIRENTRYTYPE_UNKNOWN values returned by RTDirRead. + * + * @returns IPRT status code (see RTPathQueryInfo). + * @param pszComposedName The path to the directory entry. The caller must + * compose this, it's NOT sufficient to pass + * RTDIRENTRY::szName! + * @param fFollowSymlinks Whether to follow symbolic links or not. + * @param penmType Pointer to the RTDIRENTRY::enmType member. If this + * is not RTDIRENTRYTYPE_UNKNOWN and, if + * @a fFollowSymlinks is false, not + * RTDIRENTRYTYPE_SYMLINK, the function will return + * immediately without doing anything. Otherwise it + * will use RTPathQueryInfo to try figure out the + * correct value. On failure, this will be unchanged. + */ +RTDECL(int) RTDirQueryUnknownType(const char *pszComposedName, bool fFollowSymlinks, RTDIRENTRYTYPE *penmType); + +/** + * Resolves RTDIRENTRYTYPE_UNKNOWN values returned by RTDirRead, extended + * version. + * + * @returns IPRT status code (see RTPathQueryInfo). + * @param pszComposedName The path to the directory entry. The caller must + * compose this, it's NOT sufficient to pass + * RTDIRENTRY::szName! + * @param fFollowSymlinks Whether to follow symbolic links or not. + * @param penmType Pointer to the RTDIRENTRY::enmType member or + * similar. Will NOT be checked on input. + * @param pObjInfo The object info buffer to use with RTPathQueryInfo. + */ +RTDECL(int) RTDirQueryUnknownTypeEx(const char *pszComposedName, bool fFollowSymlinks, RTDIRENTRYTYPE *penmType, PRTFSOBJINFO pObjInfo); + +/** + * Checks if the directory entry returned by RTDirRead is '.', '..' or similar. + * + * @returns true / false. + * @param pDirEntry The directory entry to check. + */ +RTDECL(bool) RTDirEntryIsStdDotLink(PRTDIRENTRY pDirEntry); + +/** + * Checks if the directory entry returned by RTDirReadEx is '.', '..' or + * similar. + * + * @returns true / false. + * @param pDirEntryEx The extended directory entry to check. + */ +RTDECL(bool) RTDirEntryExIsStdDotLink(PCRTDIRENTRYEX pDirEntryEx); /** * Renames a file. diff --git a/include/iprt/dvm.h b/include/iprt/dvm.h index f36a5f10..4501856e 100644 --- a/include/iprt/dvm.h +++ b/include/iprt/dvm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-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/include/iprt/env.h b/include/iprt/env.h index 64277d12..d956a06e 100644 --- a/include/iprt/env.h +++ b/include/iprt/env.h @@ -3,7 +3,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; @@ -89,6 +89,8 @@ RTDECL(int) RTEnvDestroy(RTENV Env); * @returns NULL if Env is NULL or invalid. * * @param Env Environment block handle. + * @todo This needs to change to return a copy of the env vars like + * RTEnvQueryUtf16Block does! */ RTDECL(char const * const *) RTEnvGetExecEnvP(RTENV Env); @@ -120,6 +122,8 @@ RTDECL(void) RTEnvFreeUtf16Block(PRTUTF16 pwszzBlock); * codeset conversion. We'll figure this out when it becomes necessary. */ RTDECL(bool) RTEnvExist(const char *pszVar); +RTDECL(bool) RTEnvExistsBad(const char *pszVar); +RTDECL(bool) RTEnvExistsUtf8(const char *pszVar); /** * Checks if an environment variable exists in a specific environment block. @@ -145,6 +149,8 @@ RTDECL(bool) RTEnvExistEx(RTENV Env, const char *pszVar); * codeset conversion. We'll figure this out when it becomes necessary. */ RTDECL(const char *) RTEnvGet(const char *pszVar); +RTDECL(const char *) RTEnvGetBad(const char *pszVar); +RTDECL(int) RTEnvGetUtf8(const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual); /** * Gets an environment variable in a specific environment block. @@ -173,6 +179,8 @@ RTDECL(int) RTEnvGetEx(RTENV Env, const char *pszVar, char *pszValue, size_t cbV * codeset conversion. We'll figure this out when it becomes necessary. */ RTDECL(int) RTEnvPut(const char *pszVarEqualValue); +RTDECL(int) RTEnvPutBad(const char *pszVarEqualValue); +RTDECL(int) RTEnvPutUtf8(const char *pszVarEqualValue); /** * Puts a copy of the passed in 'variable=value' string into the environment block. @@ -197,6 +205,8 @@ RTDECL(int) RTEnvPutEx(RTENV Env, const char *pszVarEqualValue); * codeset conversion. We'll figure this out when it becomes necessary. */ RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue); +RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue); +RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue); /** * Sets an environment variable (setenv(,,1)). @@ -221,6 +231,8 @@ RTDECL(int) RTEnvSetEx(RTENV Env, const char *pszVar, const char *pszValue); * codeset conversion. We'll figure this out when it becomes necessary. */ RTDECL(int) RTEnvUnset(const char *pszVar); +RTDECL(int) RTEnvUnsetBad(const char *pszVar); +RTDECL(int) RTEnvUnsetUtf8(const char *pszVar); /** * Removes an environment variable from the specified environment block. diff --git a/include/iprt/err.h b/include/iprt/err.h index 13b9914f..5a613d84 100644 --- a/include/iprt/err.h +++ b/include/iprt/err.h @@ -3,7 +3,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; @@ -654,6 +654,8 @@ RT_C_DECLS_END #define VERR_VERSION_MISMATCH (-11) /** The request function is not implemented. */ #define VERR_NOT_IMPLEMENTED (-12) +/** Invalid flags was given. */ +#define VERR_INVALID_FLAGS (-13) /** Not equal. */ #define VERR_NOT_EQUAL (-18) @@ -875,6 +877,12 @@ RT_C_DECLS_END #define VERR_UNEVEN_INPUT (-22402) /** Something is not available or not working properly. */ #define VERR_NOT_AVAILABLE (-22403) +/** The RTPROC_FLAGS_DETACHED flag isn't supported. */ +#define VERR_PROC_DETACH_NOT_SUPPORTED (-22404) +/** An account is restricted in a certain way. */ +#define VERR_ACCOUNT_RESTRICTED (-22405) +/** An account is restricted in a certain way. */ +#define VINF_ACCOUNT_RESTRICTED 22405 /** @} */ @@ -976,6 +984,8 @@ RT_C_DECLS_END #define VERR_PATH_IS_RELATIVE (-143) /** A path is not relative (start with root), expected an relative path. */ #define VERR_PATH_IS_NOT_RELATIVE (-144) +/** Zero length path. */ +#define VERR_PATH_ZERO_LENGTH (-145) /** @} */ @@ -1473,6 +1483,36 @@ RT_C_DECLS_END #define VERR_DWARF_UNKNOWN_FORM (-677) /** Encountered an unexpected attribute form. */ #define VERR_DWARF_UNEXPECTED_FORM (-678) +/** Unfinished code. */ +#define VERR_DWARF_TODO (-679) +/** Unknown location opcode. */ +#define VERR_DWARF_UNKNOWN_LOC_OPCODE (-680) +/** Expression stack overflow. */ +#define VERR_DWARF_STACK_OVERFLOW (-681) +/** Expression stack underflow. */ +#define VERR_DWARF_STACK_UNDERFLOW (-682) +/** Internal processing error in the DWARF code. */ +#define VERR_DWARF_IPE (-683) +/** Invalid configuration property value. */ +#define VERR_DBG_CFG_INVALID_VALUE (-684) +/** Not an integer property. */ +#define VERR_DBG_CFG_NOT_UINT_PROP (-685) +/** Deferred loading of information failed. */ +#define VERR_DBG_DEFERRED_LOAD_FAILED (-686) +/** Unfinished debug info reader code. */ +#define VERR_DBG_TODO (-687) +/** Found file, but it didn't match the search criteria. */ +#define VERR_DBG_FILE_MISMATCH (-688) +/** Internal processing error in the debug module reader code. */ +#define VERR_DBG_MOD_IPE (-689) +/** The symbol size was adjusted while adding it. */ +#define VINF_DBG_ADJUSTED_SYM_SIZE 690 +/** Unable to parse the CodeView debug information. */ +#define VERR_CV_BAD_FORMAT (-691) +/** Unfinished CodeView debug information feature. */ +#define VERR_CV_TODO (-692) +/** Internal processing error the CodeView debug information reader. */ +#define VERR_CV_IPE (-693) /** @} */ /** @name Request Packet Status Codes. @@ -1563,6 +1603,28 @@ RT_C_DECLS_END #define VERR_S3_CANCELED (-879) /** @} */ +/** @name HTTP status codes + * @{ */ +/** HTTP initialization failed. */ +#define VERR_HTTP_INIT_FAILED (-885) +/** The server has not found anything matching the URI given. */ +#define VERR_HTTP_NOT_FOUND (-886) +/** The request is for something forbidden. Authorization will not help. */ +#define VERR_HTTP_ACCESS_DENIED (-887) +/** The server did not understand the request due to bad syntax. */ +#define VERR_HTTP_BAD_REQUEST (-888) +/** Couldn't connect to the server (proxy?). */ +#define VERR_HTTP_COULDNT_CONNECT (-889) +/** SSL connection error. */ +#define VERR_HTTP_SSL_CONNECT_ERROR (-890) +/** CAcert is missing or has the wrong format. */ +#define VERR_HTTP_CACERT_WRONG_FORMAT (-891) +/** Certificate cannot be authenticated with the given CA certificates. */ +#define VERR_HTTP_CACERT_CANNOT_AUTHENTICATE (-892) +/** The current HTTP request was forcefully aborted */ +#define VERR_HTTP_ABORTED (-893) +/** @} */ + /** @name RTManifest status codes * @{ */ /** A digest type used in the manifest file isn't supported. */ @@ -1633,6 +1695,8 @@ RT_C_DECLS_END #define VERR_TAR_MALFORMED_GNU_LONGXXXX (-946) /** Too long name or link string. */ #define VERR_TAR_NAME_TOO_LONG (-947) +/** A directory entry in the archive. */ +#define VINF_TAR_DIR_PATH (948) /** @} */ /** @name RTPoll status codes @@ -1724,6 +1788,96 @@ RT_C_DECLS_END #define VERR_FILESYSTEM_CORRUPT (-22600) /** @} */ +/** @name RTZipXar status codes. + * @{ */ +/** Wrong magic value. */ +#define VERR_XAR_WRONG_MAGIC (-22700) +/** Bad header size. */ +#define VERR_XAR_BAD_HDR_SIZE (-22701) +/** Unsupported version. */ +#define VERR_XAR_UNSUPPORTED_VERSION (-22702) +/** Unsupported hashing function. */ +#define VERR_XAR_UNSUPPORTED_HASH_FUNCTION (-22703) +/** The table of content (TOC) is too small and therefore can't be valid. */ +#define VERR_XAR_TOC_TOO_SMALL (-22704) +/** The table of content (TOC) is too big. */ +#define VERR_XAR_TOC_TOO_BIG (-22705) +/** The compressed table of content is too big. */ +#define VERR_XAR_TOC_TOO_BIG_COMPRESSED (-22706) +/** The uncompressed table of content size in the header didn't match what + * ZLib returned. */ +#define VERR_XAR_TOC_UNCOMP_SIZE_MISMATCH (-22707) +/** The table of content string length didn't match the size specified in the + * header. */ +#define VERR_XAR_TOC_STRLEN_MISMATCH (-22708) +/** The table of content isn't valid UTF-8. */ +#define VERR_XAR_TOC_UTF8_ENCODING (-22709) +/** XML error while parsing the table of content. */ +#define VERR_XAR_TOC_XML_PARSE_ERROR (-22710) +/** The table of content XML document does not have a toc element. */ +#define VERR_XML_TOC_ELEMENT_MISSING (-22711) +/** The table of content XML element (toc) has sibilings, we expected it to be + * an only child or the root element (xar). */ +#define VERR_XML_TOC_ELEMENT_HAS_SIBLINGS (-22712) +/** The XAR table of content digest doesn't match. */ +#define VERR_XAR_TOC_DIGEST_MISMATCH (-22713) +/** Bad or missing XAR checksum element. */ +#define VERR_XAR_BAD_CHECKSUM_ELEMENT (-22714) +/** The hash function in the header doesn't match the one in the table of + * content. */ +#define VERR_XAR_HASH_FUNCTION_MISMATCH (-22715) +/** Bad digest length encountered in the table of content. */ +#define VERR_XAR_BAD_DIGEST_LENGTH (-22716) +/** The order of elements in the XAR file does not lend it self to expansion + * from via an I/O stream. */ +#define VERR_XAR_NOT_STREAMBLE_ELEMENT_ORDER (-22717) +/** Missing offset element in table of content sub-element. */ +#define VERR_XAR_MISSING_OFFSET_ELEMENT (-22718) +/** Bad offset element in table of content sub-element. */ +#define VERR_XAR_BAD_OFFSET_ELEMENT (-22719) +/** Missing size element in table of content sub-element. */ +#define VERR_XAR_MISSING_SIZE_ELEMENT (-22720) +/** Bad size element in table of content sub-element. */ +#define VERR_XAR_BAD_SIZE_ELEMENT (-22721) +/** Missing length element in table of content sub-element. */ +#define VERR_XAR_MISSING_LENGTH_ELEMENT (-22722) +/** Bad length element in table of content sub-element. */ +#define VERR_XAR_BAD_LENGTH_ELEMENT (-22723) +/** Bad file element in XAR table of content. */ +#define VERR_XAR_BAD_FILE_ELEMENT (-22724) +/** Missing data element for XAR file. */ +#define VERR_XAR_MISSING_DATA_ELEMENT (-22725) +/** Unknown XAR file type value. */ +#define VERR_XAR_UNKNOWN_FILE_TYPE (-22726) +/** Missing encoding element for XAR data stream. */ +#define VERR_XAR_NO_ENCODING (-22727) +/** Bad timestamp for XAR file. */ +#define VERR_XAR_BAD_FILE_TIMESTAMP (-22728) +/** Bad file mode for XAR file. */ +#define VERR_XAR_BAD_FILE_MODE (-22729) +/** Bad file user id for XAR file. */ +#define VERR_XAR_BAD_FILE_UID (-22730) +/** Bad file group id for XAR file. */ +#define VERR_XAR_BAD_FILE_GID (-22731) +/** Bad file inode device number for XAR file. */ +#define VERR_XAR_BAD_FILE_DEVICE_NO (-22732) +/** Bad file inode number for XAR file. */ +#define VERR_XAR_BAD_FILE_INODE (-22733) +/** Invalid name for XAR file. */ +#define VERR_XAR_INVALID_FILE_NAME (-22734) +/** The message digest of the extracted data does not match the one supplied. */ +#define VERR_XAR_EXTRACTED_HASH_MISMATCH (-22735) +/** The extracted data has exceeded the expected size. */ +#define VERR_XAR_EXTRACTED_SIZE_EXCEEDED (-22736) +/** The message digest of the archived data does not match the one supplied. */ +#define VERR_XAR_ARCHIVED_HASH_MISMATCH (-22737) +/** The decompressor completed without using all the input data. */ +#define VERR_XAR_UNUSED_ARCHIVED_DATA (-22738) +/** Expected the archived and extracted XAR data sizes to be the same for + * uncompressed data. */ +#define VERR_XAR_ARCHIVED_AND_EXTRACTED_SIZES_MISMATCH (-22739) +/** @} */ + /* SED-END */ diff --git a/include/iprt/err.mac b/include/iprt/err.mac index 00e330cc..39ac4e91 100644 --- a/include/iprt/err.mac +++ b/include/iprt/err.mac @@ -15,6 +15,7 @@ %define VINF_PERMISSION_DENIED 10 %define VERR_VERSION_MISMATCH (-11) %define VERR_NOT_IMPLEMENTED (-12) +%define VERR_INVALID_FLAGS (-13) %define VERR_NOT_EQUAL (-18) %define VERR_NOT_SYMLINK (-19) %define VERR_NO_TMP_MEMORY (-20) @@ -121,6 +122,9 @@ %define VINF_BUFFER_UNDERFLOW 22401 %define VERR_UNEVEN_INPUT (-22402) %define VERR_NOT_AVAILABLE (-22403) +%define VERR_PROC_DETACH_NOT_SUPPORTED (-22404) +%define VERR_ACCOUNT_RESTRICTED (-22405) +%define VINF_ACCOUNT_RESTRICTED 22405 %define VERR_FILE_IO_ERROR (-100) %define VERR_OPEN_FAILED (-101) %define VERR_FILE_NOT_FOUND (-102) @@ -168,6 +172,7 @@ %define VERR_PATH_DOES_NOT_START_WITH_ROOT (-142) %define VERR_PATH_IS_RELATIVE (-143) %define VERR_PATH_IS_NOT_RELATIVE (-144) +%define VERR_PATH_ZERO_LENGTH (-145) %define VERR_DISK_IO_ERROR (-150) %define VERR_INVALID_DRIVE (-151) %define VERR_DISK_FULL (-152) @@ -274,6 +279,7 @@ %define VERR_NET_HOST_DOWN (-464) %define VERR_NET_HOST_UNREACHABLE (-465) %define VERR_NET_PROTOCOL_ERROR (-466) +%define VERR_NET_INCOMPLETE_TX_PACKET (-467) %define VERR_TCP_SERVER_STOP (-500) %define VINF_TCP_SERVER_STOP 500 %define VERR_TCP_SERVER_SHUTDOWN (-501) @@ -371,6 +377,21 @@ %define VERR_DWARF_ABBREV_NOT_FOUND (-676) %define VERR_DWARF_UNKNOWN_FORM (-677) %define VERR_DWARF_UNEXPECTED_FORM (-678) +%define VERR_DWARF_TODO (-679) +%define VERR_DWARF_UNKNOWN_LOC_OPCODE (-680) +%define VERR_DWARF_STACK_OVERFLOW (-681) +%define VERR_DWARF_STACK_UNDERFLOW (-682) +%define VERR_DWARF_IPE (-683) +%define VERR_DBG_CFG_INVALID_VALUE (-684) +%define VERR_DBG_CFG_NOT_UINT_PROP (-685) +%define VERR_DBG_DEFERRED_LOAD_FAILED (-686) +%define VERR_DBG_TODO (-687) +%define VERR_DBG_FILE_MISMATCH (-688) +%define VERR_DBG_MOD_IPE (-689) +%define VINF_DBG_ADJUSTED_SYM_SIZE 690 +%define VERR_CV_BAD_FORMAT (-691) +%define VERR_CV_TODO (-692) +%define VERR_CV_IPE (-693) %define VERR_RT_REQUEST_INVALID_TYPE (-700) %define VERR_RT_REQUEST_STATE (-701) %define VERR_RT_REQUEST_INVALID_PACKAGE (-702) @@ -394,6 +415,15 @@ %define VERR_S3_BUCKET_ALREADY_EXISTS (-877) %define VERR_S3_BUCKET_NOT_EMPTY (-878) %define VERR_S3_CANCELED (-879) +%define VERR_HTTP_INIT_FAILED (-885) +%define VERR_HTTP_NOT_FOUND (-886) +%define VERR_HTTP_ACCESS_DENIED (-887) +%define VERR_HTTP_BAD_REQUEST (-888) +%define VERR_HTTP_COULDNT_CONNECT (-889) +%define VERR_HTTP_SSL_CONNECT_ERROR (-890) +%define VERR_HTTP_CACERT_WRONG_FORMAT (-891) +%define VERR_HTTP_CACERT_CANNOT_AUTHENTICATE (-892) +%define VERR_HTTP_ABORTED (-893) %define VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE (-900) %define VERR_MANIFEST_WRONG_FILE_FORMAT (-901) %define VERR_MANIFEST_DIGEST_MISMATCH (-902) @@ -424,6 +454,7 @@ %define VERR_TAR_BAD_CHKSUM_FIELD (-945) %define VERR_TAR_MALFORMED_GNU_LONGXXXX (-946) %define VERR_TAR_NAME_TOO_LONG (-947) +%define VINF_TAR_DIR_PATH (948) %define VERR_POLL_HANDLE_NOT_POLLABLE (-950) %define VERR_POLL_HANDLE_ID_EXISTS (-951) %define VERR_POLL_HANDLE_ID_NOT_FOUND (-952) @@ -453,3 +484,43 @@ %define VINF_SYS_MAY_POWER_OFF (22501) %define VERR_SYS_SHUTDOWN_FAILED (-22502) %define VERR_FILESYSTEM_CORRUPT (-22600) +%define VERR_XAR_WRONG_MAGIC (-22700) +%define VERR_XAR_BAD_HDR_SIZE (-22701) +%define VERR_XAR_UNSUPPORTED_VERSION (-22702) +%define VERR_XAR_UNSUPPORTED_HASH_FUNCTION (-22703) +%define VERR_XAR_TOC_TOO_SMALL (-22704) +%define VERR_XAR_TOC_TOO_BIG (-22705) +%define VERR_XAR_TOC_TOO_BIG_COMPRESSED (-22706) +%define VERR_XAR_TOC_UNCOMP_SIZE_MISMATCH (-22707) +%define VERR_XAR_TOC_STRLEN_MISMATCH (-22708) +%define VERR_XAR_TOC_UTF8_ENCODING (-22709) +%define VERR_XAR_TOC_XML_PARSE_ERROR (-22710) +%define VERR_XML_TOC_ELEMENT_MISSING (-22711) +%define VERR_XML_TOC_ELEMENT_HAS_SIBLINGS (-22712) +%define VERR_XAR_TOC_DIGEST_MISMATCH (-22713) +%define VERR_XAR_BAD_CHECKSUM_ELEMENT (-22714) +%define VERR_XAR_HASH_FUNCTION_MISMATCH (-22715) +%define VERR_XAR_BAD_DIGEST_LENGTH (-22716) +%define VERR_XAR_NOT_STREAMBLE_ELEMENT_ORDER (-22717) +%define VERR_XAR_MISSING_OFFSET_ELEMENT (-22718) +%define VERR_XAR_BAD_OFFSET_ELEMENT (-22719) +%define VERR_XAR_MISSING_SIZE_ELEMENT (-22720) +%define VERR_XAR_BAD_SIZE_ELEMENT (-22721) +%define VERR_XAR_MISSING_LENGTH_ELEMENT (-22722) +%define VERR_XAR_BAD_LENGTH_ELEMENT (-22723) +%define VERR_XAR_BAD_FILE_ELEMENT (-22724) +%define VERR_XAR_MISSING_DATA_ELEMENT (-22725) +%define VERR_XAR_UNKNOWN_FILE_TYPE (-22726) +%define VERR_XAR_NO_ENCODING (-22727) +%define VERR_XAR_BAD_FILE_TIMESTAMP (-22728) +%define VERR_XAR_BAD_FILE_MODE (-22729) +%define VERR_XAR_BAD_FILE_UID (-22730) +%define VERR_XAR_BAD_FILE_GID (-22731) +%define VERR_XAR_BAD_FILE_DEVICE_NO (-22732) +%define VERR_XAR_BAD_FILE_INODE (-22733) +%define VERR_XAR_INVALID_FILE_NAME (-22734) +%define VERR_XAR_EXTRACTED_HASH_MISMATCH (-22735) +%define VERR_XAR_EXTRACTED_SIZE_EXCEEDED (-22736) +%define VERR_XAR_ARCHIVED_HASH_MISMATCH (-22737) +%define VERR_XAR_UNUSED_ARCHIVED_DATA (-22738) +%define VERR_XAR_ARCHIVED_AND_EXTRACTED_SIZES_MISMATCH (-22739) diff --git a/include/iprt/err.sed b/include/iprt/err.sed index 2271331c..89cfeafd 100644 --- a/include/iprt/err.sed +++ b/include/iprt/err.sed @@ -3,7 +3,7 @@ # # -# Copyright (C) 2006-2009 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/include/iprt/file.h b/include/iprt/file.h index 3357ab23..616daceb 100644 --- a/include/iprt/file.h +++ b/include/iprt/file.h @@ -3,7 +3,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; @@ -30,6 +30,7 @@ #include #include #include +#include RT_C_DECLS_BEGIN @@ -147,7 +148,7 @@ RTDECL(int) RTFileQuerySize(const char *pszPath, uint64_t *pcbFile); #define RTFILE_O_NOT_CONTENT_INDEXED UINT32_C(0x00000800) /** Truncate the file. * @remarks This will not truncate files opened for read-only. - * @remarks The trunction doesn't have to be atomically, so anyone else opening + * @remarks The truncation doesn't have to be atomically, so anyone else opening * the file may be racing us. The caller is responsible for not causing * this race. */ #define RTFILE_O_TRUNCATE UINT32_C(0x00001000) @@ -380,6 +381,20 @@ RTDECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcbRe */ RTDECL(int) RTFileReadAt(RTFILE File, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead); +/** + * Read bytes from a file at a given offset into a S/G buffer. + * This function may modify the file position. + * + * @returns iprt status code. + * @param hFile Handle to the file. + * @param off Where to read. + * @param pSgBuf Pointer to the S/G buffer to read into. + * @param cbToRead How much to read. + * @param *pcbRead How much we actually read . + * If NULL an error will be returned for a partial read. + */ +RTDECL(int) RTFileSgReadAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToRead, size_t *pcbRead); + /** * Write bytes to a file. * @@ -406,6 +421,20 @@ RTDECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, size_ */ RTDECL(int) RTFileWriteAt(RTFILE File, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten); +/** + * Write bytes from a S/G buffer to a file at a given offset. + * This function may modify the file position. + * + * @returns iprt status code. + * @param hFile Handle to the file. + * @param off Where to write. + * @param pSgBuf What to write. + * @param cbToWrite How much to write. + * @param *pcbWritten How much we actually wrote. + * If NULL an error will be returned for a partial write. + */ +RTDECL(int) RTFileSgWriteAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToWrite, size_t *pcbWritten); + /** * Flushes the buffers for the specified file. * @@ -570,6 +599,54 @@ RTDECL(int) RTFileRename(const char *pszSrc, const char *pszDst, unsigned fRenam #define RTFILEMOVE_FLAGS_NO_SYMLINKS 0x2 /** @} */ +/** + * Converts file opening modes (used by fopen, for example) to IPRT + * compatible flags, which then can be used with RTFileOpen* APIs. + * + * Note: Handling sharing modes is not supported yet, so RTFILE_O_DENY_NONE + * will be used by default. + * + * @return IPRT status code. + * @param pszMode Mode string to convert. + * @param puMode Where to store the converted mode flags + * on success. + */ +RTDECL(int) RTFileModeToFlags(const char *pszMode, uint64_t *puMode); + +/** + * Converts file opening modes along with a separate disposition command + * to IPRT compatible flags, which then can be used with RTFileOpen* APIs. + * + * Access modes: + * "r" - Opens a file for reading. + * "r+" - Opens a file for reading and writing. + * "w" - Opens a file for writing. + * "w+" - Opens a file for writing and reading. + * + * Disposition modes: + * "ca" - Creates a new file, always. Overwrites an existing file. + * "ce" - Creates a new file if it does not exist. Fail if exist. + * "oa" - Opens an existing file and places the file pointer at + * the end of the file, if opened with write access. + * Create the file if it does not exist. + * "oc" - Opens an existing file or create it if it does not exist. + * "oe" - Opens an existing file or fail if it does not exist. + * "ot" - Opens and truncate an existing file or fail if it does not exist. + * + * Sharing modes: + * Not implemented yet. RTFILE_O_DENY_NONE will be + * used by default. + * + * @return IPRT status code. + * @param pszAccess Access mode string to convert. + * @param pszDisposition Disposition mode string to convert. + * @param pszSharing Sharing mode string to convert. Not + * implemented yet. + * @param puMode Where to store the converted mode flags + * on success. + */ +RTDECL(int) RTFileModeToFlagsEx(const char *pszAccess, const char *pszDisposition, const char *pszSharing, uint64_t *puMode); + /** * Moves a file. * @@ -1215,13 +1292,22 @@ RTDECL(int) RTFileAioReqGetRC(RTFILEAIOREQ hReq, size_t *pcbTransferred); * to handle. Pass RTFILEAIO_UNLIMITED_REQS if the * context should support an unlimited number of * requests. + * @param fFlags Combination of RTFILEAIOCTX_FLAGS_*. */ -RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax); +RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax, + uint32_t fFlags); /** Unlimited number of requests. * Used with RTFileAioCtxCreate and RTFileAioCtxGetMaxReqCount. */ #define RTFILEAIO_UNLIMITED_REQS UINT32_MAX +/** When set RTFileAioCtxWait() will always wait for completing requests, + * even when there is none waiting currently, instead of returning + * VERR_FILE_AIO_NO_REQUEST. */ +#define RTFILEAIOCTX_FLAGS_WAIT_WITHOUT_PENDING_REQUESTS RT_BIT_32(0) +/** mask of valid flags. */ +#define RTFILEAIOCTX_FLAGS_VALID_MASK (RTFILEAIOCTX_FLAGS_WAIT_WITHOUT_PENDING_REQUESTS) + /** * Destroys an async I/O context. * diff --git a/include/iprt/formats/Makefile.kup b/include/iprt/formats/Makefile.kup new file mode 100644 index 00000000..e69de29b diff --git a/include/iprt/formats/codeview.h b/include/iprt/formats/codeview.h new file mode 100644 index 00000000..b40e8f64 --- /dev/null +++ b/include/iprt/formats/codeview.h @@ -0,0 +1,82 @@ +/** @file + * IPRT - Microsoft CodeView Debug Information. + */ + +/* + * Copyright (C) 2009-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 ___iprt_formats_codeview_h +#define ___iprt_formats_codeview_h + + +#include +#include + + +/** @defgroup grp_rt_fmt_codeview Microsoft CodeView Debug Information + * @{ + */ +/** + * PDB v2.0 in image debug info. + * The URL is constructed from the timestamp and age? + */ +typedef struct CVPDB20INFO +{ + uint32_t u32Magic; /**< CVPDB20INFO_SIGNATURE. */ + int32_t offDbgInfo; /**< Always 0. Used to be the offset to the real debug info. */ + uint32_t uTimestamp; + uint32_t uAge; + uint8_t szPdbFilename[4]; +} CVPDB20INFO; +/** Pointer to in executable image PDB v2.0 info. */ +typedef CVPDB20INFO *PCVPDB20INFO; +/** Pointer to read only in executable image PDB v2.0 info. */ +typedef CVPDB20INFO const *PCCVPDB20INFO; +/** The CVPDB20INFO magic value. */ +#define CVPDB20INFO_MAGIC RT_MAKE_U32_FROM_U8('N','B','1','0') + +/** + * PDB v7.0 in image debug info. + * The URL is constructed from the signature and the age. + */ +#pragma pack(4) +typedef struct CVPDB70INFO +{ + uint32_t u32Magic; /**< CVPDB70INFO_SIGNATURE. */ + RTUUID PdbUuid; + uint32_t uAge; + uint8_t szPdbFilename[4]; +} CVPDB70INFO; +#pragma pack() +AssertCompileMemberOffset(CVPDB70INFO, PdbUuid, 4); +AssertCompileMemberOffset(CVPDB70INFO, uAge, 4 + 16); +/** Pointer to in executable image PDB v7.0 info. */ +typedef CVPDB70INFO *PCVPDB70INFO; +/** Pointer to read only in executable image PDB v7.0 info. */ +typedef CVPDB70INFO const *PCCVPDB70INFO; +/** The CVPDB70INFO magic value. */ +#define CVPDB70INFO_MAGIC RT_MAKE_U32_FROM_U8('R','S','D','S') + + +/** @} */ + +#endif + diff --git a/include/iprt/formats/hfs.h b/include/iprt/formats/hfs.h new file mode 100644 index 00000000..77d31b6a --- /dev/null +++ b/include/iprt/formats/hfs.h @@ -0,0 +1,677 @@ +/** @file + * IPRT - Hierarchical File System (HFS). + */ + +/* + * Copyright (C) 2009-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 ___iprt_formats_hfs_h +#define ___iprt_formats_hfs_h + + +#include +#include + + +/** @defgroup grp_rt_fmt_hfs HFS - Hierarchical File System. + * @{ + */ + + +/** @name HFS signature words (HFSPlusVolumeHeader::signature) + * @{ */ +#define kHFSSigWord UINT16_C(0x4244) +#define kHFSPlusSigWord UINT16_C(0x482b) +#define kHFSXSigWord UINT16_C(0x4858) +/** @} */ + +/** @name HFS version numbers (HFSPlusVolumeHeader::version). + * @{ */ +#define kHFSPlusVersion UINT16_C(4) +#define kHFSXVersion UINT16_C(5) +/** @} */ + +/** @name HFS mount version numbers (HFSPlusVolumeHeader::lastMountedVersion). + * @{ */ +#define kHFSPlusMountVersion UINT32_C(0x31302e30) +#define kHFSJMountVersion UINT32_C(0x4846534a) +#define kFSKMountVersion UINT32_C(0x46534b21) +/** @} */ + +/** @name Hard link file creators & types. + * @{ */ +#define kHardLinkFileType UINT32_C(0x686c6e6b) +#define kHFSPlusCreator UINT32_C(0x6866732b) +/** @} */ + +/** @name Symlink file creators & types. + * @{ */ +#define kSymLinkFileType UINT32_C(0x736c6e6b) +#define kSymLinkCreator UINT32_C(0x72686170) +/** @} */ + +/** @name Name limits. + * @{ */ +#define kHFSMaxVolumeNameChars UINT8_C(0x1b) +#define kHFSMaxFileNameChars UINT8_C(0x1f) +#define kHFSPlusMaxFileNameChars UINT8_C(0xff) +#define kHFSMaxAttrNameLen UINT8_C(0x7f) +/** @} */ + +/** @name Extent descriptor record densities + * @{ */ +#define kHFSExtentDensity UINT8_C(3) +#define kHFSPlusExtentDensity UINT8_C(8) +/** @} */ + + +/** @name File IDs (various fileID members). + * @{ */ +#define kHFSRootParentID UINT32_C(0x00000001) +#define kHFSRootFolderID UINT32_C(0x00000002) +#define kHFSExtentsFileID UINT32_C(0x00000003) +#define kHFSCatalogFileID UINT32_C(0x00000004) +#define kHFSBadBlockFileID UINT32_C(0x00000005) +#define kHFSAllocationFileID UINT32_C(0x00000006) +#define kHFSStartupFileID UINT32_C(0x00000007) +#define kHFSAttributesFileID UINT32_C(0x00000008) +#define kHFSAttributeDataFileID UINT32_C(0x0000000c) +#define kHFSRepairCatalogFileID UINT32_C(0x0000000e) +#define kHFSBogusExtentFileID UINT32_C(0x0000000f) +#define kHFSFirstUserCatalogNodeID UINT32_C(0x00000010) +/** @} */ + +/** @name Catalog record types. + * @{ */ +#define kHFSFolderRecord UINT16_C(0x0100) +#define kHFSFileRecord UINT16_C(0x0200) +#define kHFSFolderThreadRecord UINT16_C(0x0300) +#define kHFSFileThreadRecord UINT16_C(0x0400) +#define kHFSPlusFolderRecord UINT16_C(0x0001) +#define kHFSPlusFileRecord UINT16_C(0x0002) +#define kHFSPlusFolderThreadRecord UINT16_C(0x0003) +#define kHFSPlusFileThreadRecord UINT16_C(0x0004) +/** @} */ + +/** @name File record bits and masks. + * @{ */ +#define kHFSFileLockedBit 0 +#define kHFSThreadExistsBit 1 +#define kHFSHasAttributesBit 2 +#define kHFSHasSecurityBit 3 +#define kHFSHasFolderCountBit 4 +#define kHFSHasLinkChainBit 5 +#define kHFSHasChildLinkBit 6 +#define kHFSHasDateAddedBit 7 + +#define kHFSFileLockedMask RT_BIT(kHFSFileLockedBit) +#define kHFSThreadExistsMask RT_BIT(kHFSThreadExistsBit) +#define kHFSHasAttributesMask RT_BIT(kHFSHasAttributesBit) +#define kHFSHasSecurityMask RT_BIT(kHFSHasSecurityBit) +#define kHFSHasFolderCountMask RT_BIT(kHFSHasFolderCountBit) +#define kHFSHasLinkChainMask RT_BIT(kHFSHasLinkChainBit) +#define kHFSHasChildLinkMask RT_BIT(kHFSHasChildLinkBit) +#define kHFSHasDateAddedMask RT_BIT(kHFSHasDateAddedBit) +/** @} */ + +/** @name Key and node lengths. + * @{ */ +#define kHFSPlusAttrKeyMaximumLength ( sizeof(HFSPlusAttrKey) - sizeof(uint16_t) ) +#define kHFSPlusAttrKeyMinimumLength ( kHFSPlusAttrKeyMaximumLength - (kHFSMaxAttrNameLen * sizeof(uint16_t)) ) +#define kHFSPlusExtentKeyMaximumLength ( sizeof(HFSPlusExtentKey) - sizeof(uint16_t), +#define kHFSExtentKeyMaximumLength ( sizeof(HFSExtentKey) - sizeof(uint8_t) ) +#define kHFSPlusCatalogKeyMaximumLength ( sizeof(HFSPlusCatalogKey) - sizeof(uint16_t) ) +#define kHFSPlusCatalogKeyMinimumLength ( kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(uint16_t) ) +#define kHFSCatalogKeyMaximumLength ( sizeof(HFSCatalogKey) - sizeof(uint8_t) ) +#define kHFSCatalogKeyMinimumLength ( kHFSCatalogKeyMaximumLength - kHFSMaxFileNameChars - 1 + sizeof(uint8_t) ) +#define kHFSPlusCatalogMinNodeSize UINT16_C(0x1000) +#define kHFSPlusExtentMinNodeSize UINT16_C(0x0200) +#define kHFSPlusAttrMinNodeSize UINT16_C(0x1000) +/** @} */ + +/** @name Volume Attribute bits and masks. + * @remarks HFS has only 16-bit wide field, HFS+ has 32-bit. + * @{ */ +#define kHFSVolumeHardwareLockBit 7 +#define kHFSVolumeUnmountedBit 8 +#define kHFSVolumeSparedBlocksBit 9 +#define kHFSVolumeNoCacheRequiredBit 10 +#define kHFSBootVolumeInconsistentBit 11 +#define kHFSCatalogNodeIDsReusedBit 12 +#define kHFSVolumeJournaledBit 13 +#define kHFSVolumeInconsistentBit 14 +#define kHFSVolumeSoftwareLockBit 15 +#define kHFSUnusedNodeFixBit 31 +#define kHFSContentProtectionBit 30 + +#define kHFSVolumeHardwareLockMask RT_BIT(kHFSVolumeHardwareLockBit) +#define kHFSVolumeUnmountedMask RT_BIT(kHFSVolumeUnmountedBit) +#define kHFSVolumeSparedBlocksMask RT_BIT(kHFSVolumeSparedBlocksBit) +#define kHFSVolumeNoCacheRequiredMask RT_BIT(kHFSVolumeNoCacheRequiredBit) +#define kHFSBootVolumeInconsistentMask RT_BIT(kHFSBootVolumeInconsistentBit) +#define kHFSCatalogNodeIDsReusedMask RT_BIT(kHFSCatalogNodeIDsReusedBit) +#define kHFSVolumeJournaledMask RT_BIT(kHFSVolumeJournaledBit) +#define kHFSVolumeInconsistentMask RT_BIT(kHFSVolumeInconsistentBit) +#define kHFSVolumeSoftwareLockMask RT_BIT(kHFSVolumeSoftwareLockBit) +#define kHFSUnusedNodeFixMask RT_BIT(kHFSUnusedNodeFixBit) +#define kHFSContentProtectionMask RT_BIT(kHFSContentProtectionBit) + +#define kHFSMDBAttributesMask UINT16_C(0x8380) +/** @} */ + +/** @name Misc + * @{ */ +#define kHFSUnusedNodesFixDate UINT32_C(0xc5ef2480) + +#define HFSPLUSMETADATAFOLDER "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data" +#define HFSPLUS_DIR_METADATA_FOLDER ".HFS+ Private Directory Data\xd" +#define HFS_INODE_PREFIX "iNode" +#define HFS_DELETE_PREFIX "temp" +#define HFS_DIRINODE_PREFIX "dir_" +#define FIRST_LINK_XATTR_NAME "com.apple.system.hfs.firstlink" +#define FIRST_LINK_XATTR_REC_SIZE ( sizeof(HFSPlusAttrData) + 10 ) + +/* {b3e20f39-f292-11d6-97a4-00306543ecac} */ +#define HFS_UUID_NAMESPACE_ID "\xB3\xE2\x0F\x39\xF2\x92\x11\xD6\x97\xA4\x00\x30\x65\x43\xEC\xAC" + +#define SET_HFS_TEXT_ENCODING(a_uHint) (UINT32_C(0x656e6300) | (uint8_t)(a_uHint)) +#define GET_HFS_TEXT_ENCODING(a_uHint) ( ((a_uHint) & UINT32_C(0xffffff00)) == UINT32_C(0x656e6300) \ + ? UINT32_C(0x000000ff)(a_uHint) : UINT32_MAX) +/** @} */ + +/** @name B-tree stuff. + * @{ */ +#define kMaxKeyLength 520 + +#define kBTLeafNode (-1) +#define kBTIndexNode 0 +#define kBTHeaderNode 1 +#define kBTMapNode 2 + +#define kBTBadCloseMask RT_BIT_32(0) +#define kBTBigKeysMask RT_BIT_32(1) +#define kBTVariableIndexKeysMask RT_BIT_32(2) + +/** @} */ + +/** @name B-tree compare types (BTHeaderRec::keyCompareType) */ +#define kHFSCaseFolding UINT8_C(0xcf) +#define kHFSBinaryCompare UINT8_C(0xbc) +/** @} */ + +/** @name Journal stuff. + * @{ */ +#define JIB_RESERVED_SIZE ( sizeof(uint32_t) * 32 - 85 ) + +#define kJIJournalInFSMask RT_BIT_32(0) +#define kJIJournalOnOtherDeviceMask RT_BIT_32(1) +#define kJIJournalNeedInitMask RT_BIT_32(2) + +#define EXTJNL_CONTENT_TYPE_UUID "4a6f7572-6e61-11aa-aa11-00306543ecac" +/** @} */ + + + +typedef struct HFSUniStr255 +{ + uint16_t length; + RTUTF16 unicode[255]; +} HFSUniStr255; +AssertCompileSize(HFSUniStr255, 0x200); +typedef const HFSUniStr255 * ConstHFSUniStr255Param; + +#pragma pack(1) +typedef struct HFSExtentKey +{ + uint8_t keyLength; + uint8_t forkType; + uint32_t fileID; /**< Misaligned. */ + uint16_t startBLock; +} HFSExtentKey; +#pragma pack() +AssertCompileSize(HFSExtentKey, 8); + +typedef struct HFSPlusExtentKey +{ + uint16_t keyLength; + uint8_t forkType; + uint8_t pad; + uint32_t fileID; + uint32_t startBlock; +} HFSPlusExtentKey; +AssertCompileSize(HFSPlusExtentKey, 12); + +typedef struct HFSExtentDescriptor +{ + uint16_t startBlock; + uint16_t blockCount; +} HFSExtentDescriptor; +AssertCompileSize(HFSExtentDescriptor, 4); + +typedef struct HFSPlusExtentDescriptor +{ + uint32_t startBlock; + uint32_t blockCount; +} HFSPlusExtentDescriptor; +AssertCompileSize(HFSPlusExtentDescriptor, 8); + +typedef HFSExtentDescriptor HFSExtentRecord[3]; +typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8]; + +typedef struct FndrFileInfo +{ + uint32_t fdType; + uint32_t fdCreator; + uint16_t fdFlags; + struct + { + int16_t v; + int16_t h; + } fdLocation; + uint16_t opaque; +} FndrFileInfo; +AssertCompileSize(FndrFileInfo, 16); + +typedef struct FndrDirInfo +{ + struct + { + int16_t top; + int16_t left; + int16_t bottom; + int16_t right; + } frRect; + uint16_t frFlags; + struct + { + int16_t v; + int16_t h; + } fdLocation; + uint16_t opaque; +} FndrDirInfo; +AssertCompileSize(FndrDirInfo, 16); + +typedef struct FndrOpaqueInfo +{ + int8_t opaque[16]; +} FndrOpaqueInfo; +AssertCompileSize(FndrOpaqueInfo, 16); + +typedef struct FndrExtendedFileInfo +{ + uint32_t reserved1; + uint32_t date_added; + uint16_t extended_flags; + uint16_t reserved2; + uint32_t reserved3; +} FndrExtendedFileInfo; +AssertCompileSize(FndrExtendedFileInfo, 16); + +typedef struct FndrExtendedDirInfo +{ + uint32_t point; + uint32_t date_added; + uint16_t extended_flags; + uint16_t reserved3; + uint32_t reserved4; +} FndrExtendedDirInfo; +AssertCompileSize(FndrExtendedDirInfo, 16); + +typedef struct HFSPlusForkData +{ + uint64_t logicalSize; + uint32_t clumpSize; + uint32_t totalBlocks; + HFSPlusExtentRecord extents; +} HFSPlusForkData; +AssertCompileSize(HFSPlusForkData, 80); + +typedef struct HFSPlusBSDInfo +{ + uint32_t ownerID; + uint32_t groupID; + uint8_t adminFlags; + uint8_t ownerFlags; + uint16_t fileMode; + union + { + uint32_t iNodeNum; + uint32_t linkCount; + uint32_t rawDevice; + } special; +} HFSPlusBSDInfo; +AssertCompileSize(HFSPlusBSDInfo, 16); + +#pragma pack(1) +typedef struct HFSCatalogKey +{ + uint8_t keyLength; + uint8_t reserved; + uint32_t parentID; /**< Misaligned. */ + uint8_t nodeName[kHFSMaxFileNameChars + 1]; +} HFSCatalogKey; +#pragma pack() +AssertCompileSize(HFSCatalogKey, 0x26); + +#pragma pack(1) +typedef struct HFSPlusCatalogKey +{ + uint16_t keyLength; + uint32_t parentID; /**< Misaligned. */ + HFSUniStr255 nodeName; +} HFSPlusCatalogKey; +#pragma pack() +AssertCompileSize(HFSPlusCatalogKey, 0x206); + +#pragma pack(1) +typedef struct HFSCatalogFolder +{ + int16_t recordType; + uint16_t flags; + uint16_t valence; + uint32_t folderID; /**< Misaligned. */ + uint32_t createDate; /**< Misaligned. */ + uint32_t modifyDate; /**< Misaligned. */ + uint32_t backupDate; /**< Misaligned. */ + FndrDirInfo userInfo; + FndrOpaqueInfo finderInfo; + uint32_t reserved[4]; /**< Misaligned. */ +} HFSCatalogFolder; +#pragma pack() +AssertCompileSize(HFSCatalogFolder, 70); + +typedef struct HFSPlusCatalogFolder +{ + int16_t recordType; + uint16_t flags; + uint32_t valence; + uint32_t folderID; + uint32_t createDate; + uint32_t contentModDate; + uint32_t attributeModDate; + uint32_t accessDate; + uint32_t backupDate; + HFSPlusBSDInfo bsdInfo; + FndrDirInfo userInfo; + FndrOpaqueInfo finderInfo; + uint32_t textEncoding; + uint32_t folderCount; +} HFSPlusCatalogFolder; +AssertCompileSize(HFSPlusCatalogFolder, 88); + +#pragma pack(1) +typedef struct HFSCatalogFile +{ + int16_t recordType; + uint8_t flags; + uint8_t fileType; + FndrFileInfo userInfo; + uint32_t fileID; + uint16_t dataStartBlock; + int32_t dataLogicalSize; /**< Misaligned. */ + int32_t dataPhysicalSize; /**< Misaligned. */ + uint16_t rsrcStartBlock; + int32_t rsrcLogicalSize; + int32_t rsrcPhysicalSize; + uint32_t createDate; + uint32_t modifyDate; + uint32_t backupDate; + FndrOpaqueInfo finderInfo; + uint16_t clumpSize; + HFSExtentRecord dataExtents; /**< Misaligned. */ + HFSExtentRecord rsrcExtents; /**< Misaligned. */ + uint32_t reserved; /**< Misaligned. */ +} HFSCatalogFile; +#pragma pack() +AssertCompileSize(HFSCatalogFile, 102); + +#pragma pack(1) +typedef struct HFSPlusCatalogFile +{ + int16_t recordType; + uint16_t flags; + uint32_t reserved1; + uint32_t fileID; + uint32_t createDate; + uint32_t contentModDate; + uint32_t attributeModDate; + uint32_t accessDate; + uint32_t backupDate; + HFSPlusBSDInfo bsdInfo; + FndrFileInfo userInfo; + FndrOpaqueInfo finderInfo; + uint32_t textEncoding; + uint32_t reserved2; + HFSPlusForkData dataFork; + HFSPlusForkData resourceFork; +} HFSPlusCatalogFile; +#pragma pack() +AssertCompileMemberAlignment(HFSPlusCatalogFile, dataFork, 8); +AssertCompileSize(HFSPlusCatalogFile, 248); + +#pragma pack(1) +typedef struct HFSCatalogThread +{ + int16_t recordType; + int32_t reserved[2]; + uint32_t parentID; + uint8_t nodeName[kHFSMaxFileNameChars + 1]; +} HFSCatalogThread; +#pragma pack() +AssertCompileSize(HFSCatalogThread, 46); + +typedef struct HFSPlusCatalogThread +{ + int16_t recordType; + int16_t reserved; + uint32_t parentID; + HFSUniStr255 nodeName; +} HFSPlusCatalogThread; +AssertCompileSize(HFSPlusCatalogThread, 0x208); + +typedef struct HFSPlusAttrForkData +{ + uint32_t recordType; + uint32_t reserved; + HFSPlusForkData theFork; +} HFSPlusAttrForkData; +AssertCompileSize(HFSPlusAttrForkData, 88); + +typedef struct HFSPlusAttrExtents +{ + uint32_t recordType; + uint32_t reserved; + HFSPlusExtentRecord extents; +} HFSPlusAttrExtents; +AssertCompileSize(HFSPlusAttrExtents, 72); + +#pragma pack(1) +typedef struct HFSPlusAttrData +{ + uint32_t recordType; + uint32_t reserved[2]; + uint32_t attrSize; + uint8_t attrData[2]; /**< Causes misaligned struct size. */ +} HFSPlusAttrData; +#pragma pack() +AssertCompileSize(HFSPlusAttrData, 18); + +#pragma pack(1) +typedef struct HFSPlusAttrInlineData +{ + uint32_t recordType; + uint32_t reserved; + uint32_t logicalSize; + uint8_t userData[2]; /**< Causes misaligned struct size. */ +} HFSPlusAttrInlineData; +#pragma pack() +AssertCompileSize(HFSPlusAttrInlineData, 14); + +typedef union HFSPlusAttrRecord +{ + uint32_t recordType; + HFSPlusAttrInlineData inlineData; + HFSPlusAttrData attrData; + HFSPlusAttrForkData forkData; + HFSPlusAttrExtents overflowExtents; +} HFSPlusAttrRecord; +AssertCompileSize(HFSPlusAttrRecord, 88); + +typedef struct HFSPlusAttrKey +{ + uint16_t keyLength; + uint16_t pad; + uint32_t fileID; + uint32_t startBlock; + uint16_t attrNameLen; + RTUTF16 attrName[kHFSMaxAttrNameLen]; +} HFSPlusAttrKey; +AssertCompileSize(HFSPlusAttrKey, 268); + +#pragma pack(1) +typedef struct HFSMasterDirectoryBlock +{ + uint16_t drSigWord; + uint32_t drCrDate; /**< Misaligned. */ + uint32_t drLsMod; /**< Misaligned. */ + uint16_t drAtrb; + uint16_t drNmFls; + uint16_t drVBMSt; + uint16_t drAllocPtr; + uint16_t drNmAlBlks; + uint32_t drAlBlkSiz; + uint32_t drClpSiz; + uint16_t drAlBlSt; + uint32_t drNxCNID; /**< Misaligned. */ + uint16_t drFreeBks; + uint8_t drVN[kHFSMaxVolumeNameChars + 1]; + uint32_t drVolBkUp; + uint16_t drVSeqNum; + uint32_t drWrCnt; /**< Misaligned. */ + uint32_t drXTClpSiz; /**< Misaligned. */ + uint32_t drCTClpSiz; /**< Misaligned. */ + uint16_t drNmRtDirs; + uint32_t drFilCnt; + uint32_t drDirCnt; + uint32_t drFndrInfo[8]; + uint16_t drEmbedSigWord; + HFSExtentDescriptor drEmbedExtent; + uint32_t drXTFlSize; /**< Misaligned. */ + HFSExtentRecord drXTExtRec; + uint32_t drCTFlSize; /**< Misaligned. */ + HFSExtentRecord drCTExtRec; +} HFSMasterDirectoryBlock; +#pragma pack() +AssertCompileSize(HFSMasterDirectoryBlock, 162); + +typedef struct HFSPlusVolumeHeader +{ + uint16_t signature; + uint16_t version; + uint32_t attributes; + uint32_t lastMountedVersion; + uint32_t journalInfoBlock; + uint32_t createDate; + uint32_t modifyDate; + uint32_t backupDate; + uint32_t checkedDate; + uint32_t fileCount; + uint32_t folderCount; + uint32_t blockSize; + uint32_t totalBlocks; + uint32_t freeBlocks; + uint32_t nextAllocation; + uint32_t rsrcClumpSize; + uint32_t dataClumpSize; + uint32_t nextCatalogID; + uint32_t writeCount; + uint64_t encodingsBitmap; + uint8_t finderInfo[32]; + HFSPlusForkData allocationFile; + HFSPlusForkData extentsFile; + HFSPlusForkData catalogFile; + HFSPlusForkData attributesFile; + HFSPlusForkData startupFile; +} HFSPlusVolumeHeader; +AssertCompileMemberAlignment(HFSPlusVolumeHeader, nextCatalogID, 8); +AssertCompileSize(HFSPlusVolumeHeader, 512); + +typedef union BTreeKey +{ + uint8_t length8; + uint16_t length16; + uint8_t rawData[kMaxKeyLength + 2]; +} BTreeKey; +AssertCompileSize(BTreeKey, 522); + +#pragma pack(1) +typedef struct BTNodeDescriptor +{ + uint32_t fLink; + uint32_t bLink; + int8_t kind; + uint8_t height; + uint16_t numRecords; + uint16_t reserved; /**< Causes struct size misalignment. */ +} BTNodeDescriptor; +#pragma pack() +AssertCompileSize(BTNodeDescriptor, 14); + +#pragma pack(1) +typedef struct BTHeaderRec +{ + uint16_t treeDepth; + uint32_t rootNode; /**< Misaligned. */ + uint32_t leafRecords; /**< Misaligned. */ + uint32_t firstLeafNode; /**< Misaligned. */ + uint32_t lastLeafNode; /**< Misaligned. */ + uint16_t nodeSize; + uint16_t maxKeyLength; + uint32_t totalNodes; /**< Misaligned. */ + uint32_t freeNodes; /**< Misaligned. */ + uint16_t reserved1; + uint32_t clumpSize; + uint8_t btreeType; + uint8_t keyCompareType; + uint32_t attributes; /**< Misaligned. */ + uint32_t reserved3[16]; /**< Misaligned. */ +} BTHeaderRec; +#pragma pack() +AssertCompileSize(BTHeaderRec, 106); + +#pragma pack(1) +typedef struct JournalInfoBlock +{ + uint32_t flags; + uint32_t devices_signature[8]; + uint64_t offset; /**< Misaligned (morons). */ + uint64_t size; /**< Misaligned. */ + char ext_jnl_uuid[37]; + char machine_serial_num[48]; + char reserved[JIB_RESERVED_SIZE]; +} JournalInfoBlock; +#pragma pack() +AssertCompileSize(JournalInfoBlock, 180); + +/** @} */ + +#endif + diff --git a/include/iprt/formats/mach-o.h b/include/iprt/formats/mach-o.h new file mode 100644 index 00000000..6f51c8d3 --- /dev/null +++ b/include/iprt/formats/mach-o.h @@ -0,0 +1,626 @@ +/* $Id: mach-o.h $ */ +/** @file + * IPRT - Mach-O Structures and Constants. + */ + +/* + * Copyright (C) 2011-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 ___internal_ldrMach_O_h +#define ___internal_ldrMach_O_h + +#include + +#ifndef CPU_ARCH_MASK + +/* cputype */ +#define CPU_ARCH_MASK INT32_C(0xff000000) +#define CPU_ARCH_ABI64 INT32_C(0x01000000) +#define CPU_TYPE_ANY INT32_C(-1) +#define CPU_TYPE_VAX INT32_C(1) +#define CPU_TYPE_MC680x0 INT32_C(6) +#define CPU_TYPE_X86 INT32_C(7) +#define CPU_TYPE_I386 CPU_TYPE_X86 +#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) +#define CPU_TYPE_MC98000 INT32_C(10) +#define CPU_TYPE_HPPA INT32_C(11) +#define CPU_TYPE_MC88000 INT32_C(13) +#define CPU_TYPE_SPARC INT32_C(14) +#define CPU_TYPE_I860 INT32_C(15) +#define CPU_TYPE_POWERPC INT32_C(18) +#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) + +/* cpusubtype */ +#define CPU_SUBTYPE_MULTIPLE INT32_C(-1) +#define CPU_SUBTYPE_LITTLE_ENDIAN INT32_C(0) +#define CPU_SUBTYPE_BIG_ENDIAN INT32_C(1) + +#define CPU_SUBTYPE_VAX_ALL INT32_C(0) +#define CPU_SUBTYPE_VAX780 INT32_C(1) +#define CPU_SUBTYPE_VAX785 INT32_C(2) +#define CPU_SUBTYPE_VAX750 INT32_C(3) +#define CPU_SUBTYPE_VAX730 INT32_C(4) +#define CPU_SUBTYPE_UVAXI INT32_C(5) +#define CPU_SUBTYPE_UVAXII INT32_C(6) +#define CPU_SUBTYPE_VAX8200 INT32_C(7) +#define CPU_SUBTYPE_VAX8500 INT32_C(8) +#define CPU_SUBTYPE_VAX8600 INT32_C(9) +#define CPU_SUBTYPE_VAX8650 INT32_C(10) +#define CPU_SUBTYPE_VAX8800 INT32_C(11) +#define CPU_SUBTYPE_UVAXIII INT32_C(12) + +#define CPU_SUBTYPE_MC680x0_ALL INT32_C(1) +#define CPU_SUBTYPE_MC68030 INT32_C(1) +#define CPU_SUBTYPE_MC68040 INT32_C(2) +#define CPU_SUBTYPE_MC68030_ONLY INT32_C(3) + +#define CPU_SUBTYPE_INTEL(fam, model) ( (int32_t )(((model) << 4) | (fam)) ) +#define CPU_SUBTYPE_INTEL_FAMILY(subtype) ( (subtype) & 0xf ) +#define CPU_SUBTYPE_INTEL_MODEL(subtype) ( (subtype) >> 4 ) +#define CPU_SUBTYPE_INTEL_FAMILY_MAX 0xf +#define CPU_SUBTYPE_INTEL_MODEL_ALL 0 + +#define CPU_SUBTYPE_I386_ALL CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_386 CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_486 CPU_SUBTYPE_INTEL(4, 0) +#define CPU_SUBTYPE_486SX CPU_SUBTYPE_INTEL(4, 8) +#define CPU_SUBTYPE_586 CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENT CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENTPRO CPU_SUBTYPE_INTEL(6, 1) +#define CPU_SUBTYPE_PENTII_M3 CPU_SUBTYPE_INTEL(6, 3) +#define CPU_SUBTYPE_PENTII_M5 CPU_SUBTYPE_INTEL(6, 5) +#define CPU_SUBTYPE_CELERON CPU_SUBTYPE_INTEL(7, 6) +#define CPU_SUBTYPE_CELERON_MOBILE CPU_SUBTYPE_INTEL(7, 7) +#define CPU_SUBTYPE_PENTIUM_3 CPU_SUBTYPE_INTEL(8, 0) +#define CPU_SUBTYPE_PENTIUM_3_M CPU_SUBTYPE_INTEL(8, 1) +#define CPU_SUBTYPE_PENTIUM_3_XEON CPU_SUBTYPE_INTEL(8, 2) +#define CPU_SUBTYPE_PENTIUM_M CPU_SUBTYPE_INTEL(9, 0) +#define CPU_SUBTYPE_PENTIUM_4 CPU_SUBTYPE_INTEL(10, 0) +#define CPU_SUBTYPE_PENTIUM_4_M CPU_SUBTYPE_INTEL(10, 1) +#define CPU_SUBTYPE_ITANIUM CPU_SUBTYPE_INTEL(11, 0) +#define CPU_SUBTYPE_ITANIUM_2 CPU_SUBTYPE_INTEL(11, 1) +#define CPU_SUBTYPE_XEON CPU_SUBTYPE_INTEL(12, 0) +#define CPU_SUBTYPE_XEON_MP CPU_SUBTYPE_INTEL(12, 1) + +#define CPU_SUBTYPE_X86_ALL INT32_C(3) +#define CPU_SUBTYPE_X86_64_ALL INT32_C(3) +#define CPU_SUBTYPE_X86_ARCH1 INT32_C(4) + +#define CPU_SUBTYPE_MIPS_ALL INT32_C(0) +#define CPU_SUBTYPE_MIPS_R2300 INT32_C(1) +#define CPU_SUBTYPE_MIPS_R2600 INT32_C(2) +#define CPU_SUBTYPE_MIPS_R2800 INT32_C(3) +#define CPU_SUBTYPE_MIPS_R2000a INT32_C(4) +#define CPU_SUBTYPE_MIPS_R2000 INT32_C(5) +#define CPU_SUBTYPE_MIPS_R3000a INT32_C(6) +#define CPU_SUBTYPE_MIPS_R3000 INT32_C(7) + +#define CPU_SUBTYPE_MC98000_ALL INT32_C(0) +#define CPU_SUBTYPE_MC98601 INT32_C(1) + +#define CPU_SUBTYPE_HPPA_ALL INT32_C(0) +#define CPU_SUBTYPE_HPPA_7100 INT32_C(0) +#define CPU_SUBTYPE_HPPA_7100LC INT32_C(1) + +#define CPU_SUBTYPE_MC88000_ALL INT32_C(0) +#define CPU_SUBTYPE_MC88100 INT32_C(1) +#define CPU_SUBTYPE_MC88110 INT32_C(2) + +#define CPU_SUBTYPE_SPARC_ALL INT32_C(0) + +#define CPU_SUBTYPE_I860_ALL INT32_C(0) +#define CPU_SUBTYPE_I860_860 INT32_C(1) + +#define CPU_SUBTYPE_POWERPC_ALL INT32_C(0) +#define CPU_SUBTYPE_POWERPC_601 INT32_C(1) +#define CPU_SUBTYPE_POWERPC_602 INT32_C(2) +#define CPU_SUBTYPE_POWERPC_603 INT32_C(3) +#define CPU_SUBTYPE_POWERPC_603e INT32_C(4) +#define CPU_SUBTYPE_POWERPC_603ev INT32_C(5) +#define CPU_SUBTYPE_POWERPC_604 INT32_C(6) +#define CPU_SUBTYPE_POWERPC_604e INT32_C(7) +#define CPU_SUBTYPE_POWERPC_620 INT32_C(8) +#define CPU_SUBTYPE_POWERPC_750 INT32_C(9) +#define CPU_SUBTYPE_POWERPC_7400 INT32_C(10) +#define CPU_SUBTYPE_POWERPC_7450 INT32_C(11) +#define CPU_SUBTYPE_POWERPC_Max INT32_C(10) +#define CPU_SUBTYPE_POWERPC_SCVger INT32_C(11) +#define CPU_SUBTYPE_POWERPC_970 INT32_C(100) + +#define CPU_SUBTYPE_MASK UINT32_C(0xff000000) +#define CPU_SUBTYPE_LIB64 UINT32_C(0x80000000) + +#endif /* !CPU_ARCH_MASK */ + + +typedef struct fat_header +{ + uint32_t magic; + uint32_t nfat_arch; +} fat_header_t; + +#ifndef IMAGE_FAT_SIGNATURE +# define IMAGE_FAT_SIGNATURE UINT32_C(0xcafebabe) +#endif +#ifndef IMAGE_FAT_SIGNATURE_OE +# define IMAGE_FAT_SIGNATURE_OE UINT32_C(0xbebafeca) +#endif + +typedef struct fat_arch +{ + int32_t cputype; + int32_t cpusubtype; + uint32_t offset; + uint32_t size; + uint32_t align; +} fat_arch_t; + +typedef struct mach_header_32 +{ + uint32_t magic; + int32_t cputype; + int32_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; +} mach_header_32_t; + +/* magic */ +#ifndef IMAGE_MACHO32_SIGNATURE +# define IMAGE_MACHO32_SIGNATURE UINT32_C(0xfeedface) +#endif +#ifndef IMAGE_MACHO32_SIGNATURE_OE +# define IMAGE_MACHO32_SIGNATURE_OE UINT32_C(0xcefaedfe) +#endif +#define MH_MAGIC IMAGE_MACHO32_SIGNATURE +#define MH_CIGAM IMAGE_MACHO32_SIGNATURE_OE + +typedef struct mach_header_64 +{ + uint32_t magic; + int32_t cputype; + int32_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; + uint32_t reserved; +} mach_header_64_t; + +/* magic */ +#ifndef IMAGE_MACHO64_SIGNATURE +# define IMAGE_MACHO64_SIGNATURE UINT32_C(0xfeedfacf) +#endif +#ifndef IMAGE_MACHO64_SIGNATURE_OE +# define IMAGE_MACHO64_SIGNATURE_OE UINT32_C(0xfefaedfe) +#endif +#define MH_MAGIC_64 IMAGE_MACHO64_SIGNATURE +#define MH_CIGAM_64 IMAGE_MACHO64_SIGNATURE_OE + +/* mach_header_* filetype */ +#define MH_OBJECT UINT32_C(1) +#define MH_EXECUTE UINT32_C(2) +#define MH_FVMLIB UINT32_C(3) +#define MH_CORE UINT32_C(4) +#define MH_PRELOAD UINT32_C(5) +#define MH_DYLIB UINT32_C(6) +#define MH_DYLINKER UINT32_C(7) +#define MH_BUNDLE UINT32_C(8) +#define MH_DYLIB_STUB UINT32_C(9) +#define MH_DSYM UINT32_C(10) +#define MH_KEXT_BUNDLE UINT32_C(11) + +/* mach_header_* flags */ +#define MH_NOUNDEFS UINT32_C(0x00000001) +#define MH_INCRLINK UINT32_C(0x00000002) +#define MH_DYLDLINK UINT32_C(0x00000004) +#define MH_BINDATLOAD UINT32_C(0x00000008) +#define MH_PREBOUND UINT32_C(0x00000010) +#define MH_SPLIT_SEGS UINT32_C(0x00000020) +#define MH_LAZY_INIT UINT32_C(0x00000040) +#define MH_TWOLEVEL UINT32_C(0x00000080) +#define MH_FORCE_FLAT UINT32_C(0x00000100) +#define MH_NOMULTIDEFS UINT32_C(0x00000200) +#define MH_NOFIXPREBINDING UINT32_C(0x00000400) +#define MH_PREBINDABLE UINT32_C(0x00000800) +#define MH_ALLMODSBOUND UINT32_C(0x00001000) +#define MH_SUBSECTIONS_VIA_SYMBOLS UINT32_C(0x00002000) +#define MH_CANONICAL UINT32_C(0x00004000) +#define MH_WEAK_DEFINES UINT32_C(0x00008000) +#define MH_BINDS_TO_WEAK UINT32_C(0x00010000) +#define MH_ALLOW_STACK_EXECUTION UINT32_C(0x00020000) +#define MH_ROOT_SAFE UINT32_C(0x00040000) +#define MH_SETUID_SAFE UINT32_C(0x00080000) +#define MH_NO_REEXPORTED_DYLIBS UINT32_C(0x00100000) +#define MH_PIE UINT32_C(0x00200000) +#define MH_DEAD_STRIPPABLE_DYLIB UINT32_C(0x00400000) +#define MH_HAS_TLV_DESCRIPTORS UINT32_C(0x00800000) +#define MH_NO_HEAP_EXECUTION UINT32_C(0x01000000) +#define MH_VALID_FLAGS UINT32_C(0x01ffffff) + + +typedef struct load_command +{ + uint32_t cmd; + uint32_t cmdsize; +} load_command_t; + +/* load cmd */ +#define LC_REQ_DYLD UINT32_C(0x80000000) +#define LC_SEGMENT_32 UINT32_C(0x01) +#define LC_SYMTAB UINT32_C(0x02) +#define LC_SYMSEG UINT32_C(0x03) +#define LC_THREAD UINT32_C(0x04) +#define LC_UNIXTHREAD UINT32_C(0x05) +#define LC_LOADFVMLIB UINT32_C(0x06) +#define LC_IDFVMLIB UINT32_C(0x07) +#define LC_IDENT UINT32_C(0x08) +#define LC_FVMFILE UINT32_C(0x09) +#define LC_PREPAGE UINT32_C(0x0a) +#define LC_DYSYMTAB UINT32_C(0x0b) +#define LC_LOAD_DYLIB UINT32_C(0x0c) +#define LC_ID_DYLIB UINT32_C(0x0d) +#define LC_LOAD_DYLINKER UINT32_C(0x0e) +#define LC_ID_DYLINKER UINT32_C(0x0f) +#define LC_PREBOUND_DYLIB UINT32_C(0x10) +#define LC_ROUTINES UINT32_C(0x11) +#define LC_SUB_FRAMEWORK UINT32_C(0x12) +#define LC_SUB_UMBRELLA UINT32_C(0x13) +#define LC_SUB_CLIENT UINT32_C(0x14) +#define LC_SUB_LIBRARY UINT32_C(0x15) +#define LC_TWOLEVEL_HINTS UINT32_C(0x16) +#define LC_PREBIND_CKSUM UINT32_C(0x17) +#define LC_LOAD_WEAK_DYLIB (UINT32_C(0x18) | LC_REQ_DYLD) +#define LC_SEGMENT_64 UINT32_C(0x19) +#define LC_ROUTINES_64 UINT32_C(0x1a) +#define LC_UUID UINT32_C(0x1b) +#define LC_RPATH (UINT32_C(0x1c) | LC_REQ_DYLD) +#define LC_CODE_SIGNATURE UINT32_C(0x1d) +#define LC_SEGMENT_SPLIT_INFO UINT32_C(0x1e) +#define LC_REEXPORT_DYLIB (UINT32_C(0x1f) | LC_REQ_DYLD) +#define LC_LAZY_LOAD_DYLIB UINT32_C(0x20) +#define LC_ENCRYPTION_INFO UINT32_C(0x21) +#define LC_DYLD_INFO UINT32_C(0x22) +#define LC_DYLD_INFO_ONLY (UINT32_C(0x22) | LC_REQ_DYLD) +#define LC_LOAD_UPWARD_DYLIB (UINT32_C(0x23) | LC_REQ_DYLD) +#define LC_VERSION_MIN_MACOSX UINT32_C(0x24) +#define LC_VERSION_MIN_IPHONEOS UINT32_C(0x25) +#define LC_FUNCTION_STARTS UINT32_C(0x26) +#define LC_DYLD_ENVIRONMENT UINT32_C(0x27) +#define LC_MAIN (UINT32_C(0x28) | LC_REQ_DYLD) +#define LC_DATA_IN_CODE UINT32_C(0x29) +#define LC_SOURCE_VERSION UINT32_C(0x2a) +#define LC_DYLIB_CODE_SIGN_DRS UINT32_C(0x2b) + + +typedef struct lc_str +{ + uint32_t offset; +} lc_str_t; + +typedef struct segment_command_32 +{ + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint32_t vmaddr; + uint32_t vmsize; + uint32_t fileoff; + uint32_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; +} segment_command_32_t; + +typedef struct segment_command_64 +{ + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; +} segment_command_64_t; + +/* segment flags */ +#define SG_HIGHVM UINT32_C(0x00000001) +#define SG_FVMLIB UINT32_C(0x00000002) +#define SG_NORELOC UINT32_C(0x00000004) +#define SG_PROTECTED_VERSION_1 UINT32_C(0x00000008) + +/* maxprot/initprot */ +#ifndef VM_PROT_NONE +# define VM_PROT_NONE UINT32_C(0x00000000) +# define VM_PROT_READ UINT32_C(0x00000001) +# define VM_PROT_WRITE UINT32_C(0x00000002) +# define VM_PROT_EXECUTE UINT32_C(0x00000004) +# define VM_PROT_ALL UINT32_C(0x00000007) +#endif + +typedef struct section_32 +{ + char sectname[16]; + char segname[16]; + uint32_t addr; + uint32_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; +} section_32_t; + +typedef struct section_64 +{ + char sectname[16]; + char segname[16]; + uint64_t addr; + uint64_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; +} section_64_t; + +/* section flags */ +#define SECTION_TYPE UINT32_C(0x000000ff) +#define S_REGULAR 0x0 +#define S_ZEROFILL 0x1 +#define S_CSTRING_LITERALS 0x2 +#define S_4BYTE_LITERALS 0x3 +#define S_8BYTE_LITERALS 0x4 +#define S_LITERAL_POINTERS 0x5 +#define S_NON_LAZY_SYMBOL_POINTERS 0x6 +#define S_LAZY_SYMBOL_POINTERS 0x7 +#define S_SYMBOL_STUBS 0x8 +#define S_MOD_INIT_FUNC_POINTERS 0x9 +#define S_MOD_TERM_FUNC_POINTERS 0xa +#define S_COALESCED 0xb +#define S_GB_ZEROFILL 0xc +#define S_INTERPOSING 0xd +#define S_16BYTE_LITERALS 0xe +#define S_DTRACE_DOF 0xf +#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 + +#define SECTION_ATTRIBUTES UINT32_C(0xffffff00) +#define SECTION_ATTRIBUTES_USR UINT32_C(0xff000000) +#define S_ATTR_PURE_INSTRUCTIONS UINT32_C(0x80000000) +#define S_ATTR_NO_TOC UINT32_C(0x40000000) +#define S_ATTR_STRIP_STATIC_SYMS UINT32_C(0x20000000) +#define S_ATTR_NO_DEAD_STRIP UINT32_C(0x10000000) +#define S_ATTR_LIVE_SUPPORT UINT32_C(0x08000000) +#define S_ATTR_SELF_MODIFYING_CODE UINT32_C(0x04000000) +#define S_ATTR_DEBUG UINT32_C(0x02000000) +#define SECTION_ATTRIBUTES_SYS UINT32_C(0x00ffff00) +#define S_ATTR_SOME_INSTRUCTIONS UINT32_C(0x00000400) +#define S_ATTR_EXT_RELOC UINT32_C(0x00000200) +#define S_ATTR_LOC_RELOC UINT32_C(0x00000100) + +/* standard section names */ +#define SEG_PAGEZERO "__PAGEZERO" +#define SEG_TEXT "__TEXT" +#define SECT_TEXT "__text" +#define SECT_FVMLIB_INIT0 "__fvmlib_init0" +#define SECT_FVMLIB_INIT1 "__fvmlib_init1" +#define SEG_DATA "__DATA" +#define SECT_DATA "__data" +#define SECT_BSS "__bss" +#define SECT_COMMON "__common" +#define SEG_OBJC "__OBJC" +#define SECT_OBJC_SYMBOLS "__symbol_table" +#define SECT_OBJC_MODULES "__module_info" +#define SECT_OBJC_STRINGS "__selector_strs" +#define SECT_OBJC_REFS "__selector_refs" +#define SEG_ICON "__ICON" +#define SECT_ICON_HEADER "__header" +#define SECT_ICON_TIFF "__tiff" +#define SEG_LINKEDIT "__LINKEDIT" +#define SEG_UNIXSTACK "__UNIXSTACK" +#define SEG_IMPORT "__IMPORT" + +typedef struct thread_command +{ + uint32_t cmd; + uint32_t cmdsize; +} thread_command_t; + +typedef struct symtab_command +{ + uint32_t cmd; + uint32_t cmdsize; + uint32_t symoff; + uint32_t nsyms; + uint32_t stroff; + uint32_t strsize; +} symtab_command_t; + +typedef struct uuid_command +{ + uint32_t cmd; + uint32_t cmdsize; + uint8_t uuid[16]; +} uuid_command_t; + +typedef struct macho_nlist_32 +{ + union + { + int32_t n_strx; + } n_un; + uint8_t n_type; + uint8_t n_sect; + int16_t n_desc; + uint32_t n_value; +} macho_nlist_32_t; + + +typedef struct macho_nlist_64 +{ + union + { + uint32_t n_strx; + } n_un; + uint8_t n_type; + uint8_t n_sect; + int16_t n_desc; + uint64_t n_value; +} macho_nlist_64_t; + +#define MACHO_N_EXT UINT8_C(0x01) +#define MACHO_N_PEXT UINT8_C(0x10) + +#define MACHO_N_TYPE UINT8_C(0x0e) +#define MACHO_N_UNDF UINT8_C(0x00) +#define MACHO_N_ABS UINT8_C(0x02) +#define MACHO_N_INDR UINT8_C(0x0a) +#define MACHO_N_PBUD UINT8_C(0x0c) +#define MACHO_N_SECT UINT8_C(0x0e) + +#define MACHO_N_STAB UINT8_C(0xe0) +#define MACHO_N_GSYM UINT8_C(0x20) +#define MACHO_N_FNAME UINT8_C(0x22) +#define MACHO_N_FUN UINT8_C(0x24) +#define MACHO_N_STSYM UINT8_C(0x26) +#define MACHO_N_LCSYM UINT8_C(0x28) +#define MACHO_N_BNSYM UINT8_C(0x2e) +#define MACHO_N_PC UINT8_C(0x30) +#define MACHO_N_OPT UINT8_C(0x3c) +#define MACHO_N_RSYM UINT8_C(0x40) +#define MACHO_N_SLINE UINT8_C(0x44) +#define MACHO_N_ENSYM UINT8_C(0x4e) +#define MACHO_N_SSYM UINT8_C(0x60) +#define MACHO_N_SO UINT8_C(0x64) +#define MACHO_N_OSO UINT8_C(0x66) +#define MACHO_N_LSYM UINT8_C(0x80) +#define MACHO_N_BINCL UINT8_C(0x82) +#define MACHO_N_SOL UINT8_C(0x84) +#define MACHO_N_PARAMS UINT8_C(0x86) +#define MACHO_N_VERSION UINT8_C(0x88) +#define MACHO_N_OLEVEL UINT8_C(0x8A) +#define MACHO_N_PSYM UINT8_C(0xa0) +#define MACHO_N_EINCL UINT8_C(0xa2) +#define MACHO_N_ENTRY UINT8_C(0xa4) +#define MACHO_N_LBRAC UINT8_C(0xc0) +#define MACHO_N_EXCL UINT8_C(0xc2) +#define MACHO_N_RBRAC UINT8_C(0xe0) +#define MACHO_N_BCOMM UINT8_C(0xe2) +#define MACHO_N_ECOMM UINT8_C(0xe4) +#define MACHO_N_ECOML UINT8_C(0xe8) +#define MACHO_N_LENG UINT8_C(0xfe) + +#define MACHO_NO_SECT UINT8_C(0x00) +#define MACHO_MAX_SECT UINT8_C(0xff) + +#define REFERENCE_TYPE UINT16_C(0x000f) +#define REFERENCE_FLAG_UNDEFINED_NON_LAZY 0 +#define REFERENCE_FLAG_UNDEFINED_LAZY 1 +#define REFERENCE_FLAG_DEFINED 2 +#define REFERENCE_FLAG_PRIVATE_DEFINED 3 +#define REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4 +#define REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5 +#define REFERENCED_DYNAMICALLY UINT16_C(0x0010) + +#define GET_LIBRARY_ORDINAL(a_n_desc) \ + RT_BYTE2(a_n_desc) +#define SET_LIBRARY_ORDINAL(a_n_desc, a_ordinal) \ + do { (a_n_desc) = RT_MAKE_U16(RT_BYTE1(a_n_desc), a_ordinal); } while (0) + +#define SELF_LIBRARY_ORDINAL 0x00 +#define MAX_LIBRARY_ORDINAL 0xfd +#define DYNAMIC_LOOKUP_ORDINAL 0xfe +#define EXECUTABLE_ORDINAL 0xff + +#define N_NO_DEAD_STRIP UINT16_C(0x0020) +#define N_DESC_DISCARDED UINT16_C(0x0020) +#define N_WEAK_REF UINT16_C(0x0040) +#define N_WEAK_DEF UINT16_C(0x0080) +#define N_REF_TO_WEAK UINT16_C(0x0080) + +typedef struct macho_relocation_info +{ + int32_t r_address; + uint32_t r_symbolnum : 24; + uint32_t r_pcrel : 1; + uint32_t r_length : 2; + uint32_t r_extern : 1; + uint32_t r_type : 4; +} macho_relocation_info_t; + +#define R_ABS 0 +#define R_SCATTERED UINT32_C(0x80000000) + +typedef struct scattered_relocation_info +{ +#ifdef RT_LITTLE_ENDIAN + uint32_t r_address : 24; + uint32_t r_type : 4; + uint32_t r_length : 2; + uint32_t r_pcrel : 1; + uint32_t r_scattered : 1; +#elif defined(RT_BIG_ENDIAN) + uint32_t r_scattered : 1; + uint32_t r_pcrel : 1; + uint32_t r_length : 2; + uint32_t r_type : 4; + uint32_t r_address : 24; +#else +# error "Neither K_ENDIAN isn't LITTLE or BIG!" +#endif + int32_t r_value; +} scattered_relocation_info_t; + +typedef enum reloc_type_generic +{ + GENERIC_RELOC_VANILLA = 0, + GENERIC_RELOC_PAIR, + GENERIC_RELOC_SECTDIFF, + GENERIC_RELOC_PB_LA_PTR, + GENERIC_RELOC_LOCAL_SECTDIFF +} reloc_type_generic_t; + +typedef enum reloc_type_x86_64 +{ + X86_64_RELOC_UNSIGNED = 0, + X86_64_RELOC_SIGNED, + X86_64_RELOC_BRANCH, + X86_64_RELOC_GOT_LOAD, + X86_64_RELOC_GOT, + X86_64_RELOC_SUBTRACTOR, + X86_64_RELOC_SIGNED_1, + X86_64_RELOC_SIGNED_2, + X86_64_RELOC_SIGNED_4 +} reloc_type_x86_64_t; + +#endif + diff --git a/include/iprt/formats/mz.mac b/include/iprt/formats/mz.mac new file mode 100644 index 00000000..bdcd45f7 --- /dev/null +++ b/include/iprt/formats/mz.mac @@ -0,0 +1,56 @@ +;; @file +; IPRT - MZ (DOS Executable Header) definitions for YASM/NASM. +; + +; +; 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; +; 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 ___iprt_formats_mz_mac +%define ___iprt_formats_mz_mac + +struc IMAGE_DOS_HEADER + .e_magic resw 1 + .e_cblp resw 1 + .e_cp resw 1 + .e_crlc resw 1 + .e_cparhdr resw 1 + .e_minalloc resw 1 + .e_maxalloc resw 1 + .e_ss resw 1 + .e_sp resw 1 + .e_csum resw 1 + .e_ip resw 1 + .e_cs resw 1 + .e_lfarlc resw 1 + .e_ovno resw 1 + .e_res resw 4 + .e_oemid resw 1 + .e_oeminfo resw 1 + .e_res2 resw 10 + .e_lfanew resd 1 +endstruc + +%ifndef IMAGE_DOS_SIGNATURE + %define IMAGE_DOS_SIGNATURE 0x5a4d +%endif + +%endif + diff --git a/include/iprt/formats/pe.mac b/include/iprt/formats/pe.mac new file mode 100644 index 00000000..0d23ef54 --- /dev/null +++ b/include/iprt/formats/pe.mac @@ -0,0 +1,722 @@ +;; @file +; IPRT - Windows PE definitions for YASM/NASM. +; + +; +; 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; +; 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 ___iprt_format_pe_mac +%define ___iprt_format_pe_mac + + +;******************************************************************************* +;* Header Files * +;******************************************************************************* +%include "iprt/asmdefs.mac" + + +;******************************************************************************* +;* Defined Constants And Macros * +;******************************************************************************* +%define IMAGE_NT_SIGNATURE 0x00004550 + +; file header +%define IMAGE_FILE_MACHINE_I386 0x014c +%define IMAGE_FILE_MACHINE_AMD64 0x8664 + +%define IMAGE_FILE_RELOCS_STRIPPED 0x0001 +%define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +%define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +%define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +%define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 +%define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +%define IMAGE_FILE_16BIT_MACHINE 0x0040 +%define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +%define IMAGE_FILE_32BIT_MACHINE 0x0100 +%define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +%define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +%define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +%define IMAGE_FILE_SYSTEM 0x1000 +%define IMAGE_FILE_DLL 0x2000 +%define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +%define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + + +; optional header +%define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10B +%define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20B + +%define IMAGE_SUBSYSTEM_UNKNOWN 0x0 +%define IMAGE_SUBSYSTEM_NATIVE 0x1 +%define IMAGE_SUBSYSTEM_WINDOWS_GUI 0x2 +%define IMAGE_SUBSYSTEM_WINDOWS_CUI 0x3 +%define IMAGE_SUBSYSTEM_OS2_GUI 0x4 +%define IMAGE_SUBSYSTEM_OS2_CUI 0x5 +%define IMAGE_SUBSYSTEM_POSIX_CUI 0x7 + +%define IMAGE_LIBRARY_PROCESS_INIT 0x0001 +%define IMAGE_LIBRARY_PROCESS_TERM 0x0002 +%define IMAGE_LIBRARY_THREAD_INIT 0x0004 +%define IMAGE_LIBRARY_THREAD_TERM 0x0008 +%define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 +%define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 +%define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 +%define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 +%define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +%define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 0x10 + +%define IMAGE_DIRECTORY_ENTRY_EXPORT 0x0 +%define IMAGE_DIRECTORY_ENTRY_IMPORT 0x1 +%define IMAGE_DIRECTORY_ENTRY_RESOURCE 0x2 +%define IMAGE_DIRECTORY_ENTRY_EXCEPTION 0x3 +%define IMAGE_DIRECTORY_ENTRY_SECURITY 0x4 +%define IMAGE_DIRECTORY_ENTRY_BASERELOC 0x5 +%define IMAGE_DIRECTORY_ENTRY_DEBUG 0x6 +%define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 0x7 +%define IMAGE_DIRECTORY_ENTRY_COPYRIGHT IMAGE_DIRECTORY_ENTRY_ARCHITECTURE +%define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 0x8 +%define IMAGE_DIRECTORY_ENTRY_TLS 0x9 +%define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 0xa +%define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 0xb +%define IMAGE_DIRECTORY_ENTRY_IAT 0xc +%define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 0xd +%define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 0xe + + +; section header +%define IMAGE_SIZEOF_SHORT_NAME 0x8 + +%define IMAGE_SCN_TYPE_REG 0x00000000 +%define IMAGE_SCN_TYPE_DSECT 0x00000001 +%define IMAGE_SCN_TYPE_NOLOAD 0x00000002 +%define IMAGE_SCN_TYPE_GROUP 0x00000004 +%define IMAGE_SCN_TYPE_NO_PAD 0x00000008 +%define IMAGE_SCN_TYPE_COPY 0x00000010 + +%define IMAGE_SCN_CNT_CODE 0x00000020 +%define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +%define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +%define IMAGE_SCN_LNK_OTHER 0x00000100 +%define IMAGE_SCN_LNK_INFO 0x00000200 +%define IMAGE_SCN_TYPE_OVER 0x00000400 +%define IMAGE_SCN_LNK_REMOVE 0x00000800 +%define IMAGE_SCN_LNK_COMDAT 0x00001000 +%define IMAGE_SCN_MEM_PROTECTED 0x00004000 +%define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 +%define IMAGE_SCN_GPREL 0x00008000 +%define IMAGE_SCN_MEM_FARDATA 0x00008000 +%define IMAGE_SCN_MEM_SYSHEAP 0x00010000 +%define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +%define IMAGE_SCN_MEM_16BIT 0x00020000 +%define IMAGE_SCN_MEM_LOCKED 0x00040000 +%define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +%define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +%define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +%define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +%define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +%define IMAGE_SCN_ALIGN_16BYTES 0x00500000 +%define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +%define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +%define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +%define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +%define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +%define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +%define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +%define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +%define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 +%define IMAGE_SCN_ALIGN_MASK 0x00F00000 +%define IMAGE_SCN_ALIGN_SHIFT 20 + +%define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +%define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +%define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +%define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +%define IMAGE_SCN_MEM_SHARED 0x10000000 +%define IMAGE_SCN_MEM_EXECUTE 0x20000000 +%define IMAGE_SCN_MEM_READ 0x40000000 +%define IMAGE_SCN_MEM_WRITE 0x80000000 + + +; relocations +%define IMAGE_REL_BASED_ABSOLUTE 0x0 +%define IMAGE_REL_BASED_HIGH 0x1 +%define IMAGE_REL_BASED_LOW 0x2 +%define IMAGE_REL_BASED_HIGHLOW 0x3 +%define IMAGE_REL_BASED_HIGHADJ 0x4 +%define IMAGE_REL_BASED_MIPS_JMPADDR 0x5 +%define IMAGE_REL_BASED_MIPS_JMPADDR16 0x9 +%define IMAGE_REL_BASED_IA64_IMM64 0x9 +%define IMAGE_REL_BASED_DIR64 0xa +%define IMAGE_REL_BASED_HIGH3ADJ 0xb + + +; imports +%define IMAGE_ORDINAL_FLAG32 0x80000000 +%define IMAGE_ORDINAL_FLAG64 UINT64_MAX(0x8000000000000000) + + +; debug dir +%define IMAGE_DEBUG_TYPE_UNKNOWN UINT32_C(0x0) +%define IMAGE_DEBUG_TYPE_COFF UINT32_C(0x1) +%define IMAGE_DEBUG_TYPE_CODEVIEW UINT32_C(0x2) +%define IMAGE_DEBUG_TYPE_FPO UINT32_C(0x3) +%define IMAGE_DEBUG_TYPE_MISC UINT32_C(0x4) +%define IMAGE_DEBUG_TYPE_EXCEPTION UINT32_C(0x5) +%define IMAGE_DEBUG_TYPE_FIXUP UINT32_C(0x6) +%define IMAGE_DEBUG_TYPE_OMAP_TO_SRC UINT32_C(0x7) +%define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC UINT32_C(0x8) +%define IMAGE_DEBUG_TYPE_BORLAND UINT32_C(0x9) +%define IMAGE_DEBUG_TYPE_RESERVED10 UINT32_C(0x10) + +%define IMAGE_DEBUG_MISC_EXENAME UINT32_C(1) + +; security directory +%define WIN_CERT_REVISION_1_0 UINT16_C(0x0100) +%define WIN_CERT_REVISION_2_0 UINT16_C(0x0200) + +%define WIN_CERT_TYPE_X509 UINT16_C(1) +%define WIN_CERT_TYPE_PKCS_SIGNED_DATA UINT16_C(2) +%define WIN_CERT_TYPE_RESERVED_1 UINT16_C(3) +%define WIN_CERT_TYPE_TS_STACK_SIGNED UINT16_C(4) +%define WIN_CERT_TYPE_EFI_PKCS115 UINT16_C(0x0ef0) +%define WIN_CERT_TYPE_EFI_GUID UINT16_C(0x0ef1) + + +; For .DBG files. +%define IMAGE_SEPARATE_DEBUG_SIGNATURE UINT16_C(0x4944) + +%define IMAGE_SIZE_OF_SYMBOL 18 +%define IMAGE_SIZE_OF_SYMBOL_EX 20 + +%define IMAGE_SYM_UNDEFINED INT16_C(0) +%define IMAGE_SYM_ABSOLUTE INT16_C(-1) +%define IMAGE_SYM_DEBUG INT16_C(-2) + +%define IMAGE_SYM_CLASS_END_OF_FUNCTION UINT8_C(0xff) ; -1 +%define IMAGE_SYM_CLASS_NULL UINT8_C(0) +%define IMAGE_SYM_CLASS_AUTOMATIC UINT8_C(1) +%define IMAGE_SYM_CLASS_EXTERNAL UINT8_C(2) +%define IMAGE_SYM_CLASS_STATIC UINT8_C(3) +%define IMAGE_SYM_CLASS_REGISTER UINT8_C(4) +%define IMAGE_SYM_CLASS_EXTERNAL_DEF UINT8_C(5) +%define IMAGE_SYM_CLASS_LABEL UINT8_C(6) +%define IMAGE_SYM_CLASS_UNDEFINED_LABEL UINT8_C(7) +%define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT UINT8_C(8) +%define IMAGE_SYM_CLASS_ARGUMENT UINT8_C(9) +%define IMAGE_SYM_CLASS_STRUCT_TAG UINT8_C(10) +%define IMAGE_SYM_CLASS_MEMBER_OF_UNION UINT8_C(11) +%define IMAGE_SYM_CLASS_UNION_TAG UINT8_C(12) +%define IMAGE_SYM_CLASS_TYPE_DEFINITION UINT8_C(13) +%define IMAGE_SYM_CLASS_UNDEFINED_STATIC UINT8_C(14) +%define IMAGE_SYM_CLASS_ENUM_TAG UINT8_C(15) +%define IMAGE_SYM_CLASS_MEMBER_OF_ENUM UINT8_C(16) +%define IMAGE_SYM_CLASS_REGISTER_PARAM UINT8_C(17) +%define IMAGE_SYM_CLASS_BIT_FIELD UINT8_C(18) +%define IMAGE_SYM_CLASS_FAR_EXTERNAL UINT8_C(68) +%define IMAGE_SYM_CLASS_BLOCK UINT8_C(100) +%define IMAGE_SYM_CLASS_FUNCTION UINT8_C(101) +%define IMAGE_SYM_CLASS_END_OF_STRUCT UINT8_C(102) +%define IMAGE_SYM_CLASS_FILE UINT8_C(103) +%define IMAGE_SYM_CLASS_SECTION UINT8_C(104) +%define IMAGE_SYM_CLASS_WEAK_EXTERNAL UINT8_C(105) +%define IMAGE_SYM_CLASS_CLR_TOKEN UINT8_C(107) + + +%define IMAGE_SYM_TYPE_NULL UINT16_C(0x0000) +%define IMAGE_SYM_TYPE_VOID UINT16_C(0x0001) +%define IMAGE_SYM_TYPE_CHAR UINT16_C(0x0002) +%define IMAGE_SYM_TYPE_SHORT UINT16_C(0x0003) +%define IMAGE_SYM_TYPE_INT UINT16_C(0x0004) +%define IMAGE_SYM_TYPE_LONG UINT16_C(0x0005) +%define IMAGE_SYM_TYPE_FLOAT UINT16_C(0x0006) +%define IMAGE_SYM_TYPE_DOUBLE UINT16_C(0x0007) +%define IMAGE_SYM_TYPE_STRUCT UINT16_C(0x0008) +%define IMAGE_SYM_TYPE_UNION UINT16_C(0x0009) +%define IMAGE_SYM_TYPE_ENUM UINT16_C(0x000a) +%define IMAGE_SYM_TYPE_MOE UINT16_C(0x000b) +%define IMAGE_SYM_TYPE_BYTE UINT16_C(0x000c) +%define IMAGE_SYM_TYPE_WORD UINT16_C(0x000d) +%define IMAGE_SYM_TYPE_UINT UINT16_C(0x000e) +%define IMAGE_SYM_TYPE_DWORD UINT16_C(0x000f) +%define IMAGE_SYM_TYPE_PCODE UINT16_C(0x8000) + +%define IMAGE_SYM_DTYPE_NULL UINT16_C(0x0) +%define IMAGE_SYM_DTYPE_POINTER UINT16_C(0x1) +%define IMAGE_SYM_DTYPE_FUNCTION UINT16_C(0x2) +%define IMAGE_SYM_DTYPE_ARRAY UINT16_C(0x3) + + +%define N_BTMASK UINT16_C(0x000f) +%define N_TMASK UINT16_C(0x0030) +%define N_TMASK1 UINT16_C(0x00c0) +%define N_TMASK2 UINT16_C(0x00f0) +%define N_BTSHFT 4 +%define N_TSHIFT 2 + + +;******************************************************************************* +;* Structures and Typedefs * +;******************************************************************************* + +struc IMAGE_FILE_HEADER + .Machine resw 1 ;;< 0x00 + .NumberOfSections resw 1 ;;< 0x02 + .TimeDateStamp resd 1 ;;< 0x04 + .PointerToSymbolTable resd 1 ;;< 0x08 + .NumberOfSymbols resd 1 ;;< 0x0c + .SizeOfOptionalHeader resw 1 ;;< 0x10 + .Characteristics resw 1 ;;< 0x12 +endstruc +AssertCompileSize(IMAGE_FILE_HEADER, 0x14) + +struc IMAGE_DATA_DIRECTORY + .VirtualAddress resd 1 + .Size resd 1 +endstruc + + +struc IMAGE_OPTIONAL_HEADER32 + .Magic resw 1 ;;< 0x00 + .MajorLinkerVersion resb 1 ;;< 0x02 + .MinorLinkerVersion resb 1 ;;< 0x03 + .SizeOfCode resd 1 ;;< 0x04 + .SizeOfInitializedData resd 1 ;;< 0x08 + .SizeOfUninitializedData resd 1 ;;< 0x0c + .AddressOfEntryPoint resd 1 ;;< 0x10 + .BaseOfCode resd 1 ;;< 0x14 + .BaseOfData resd 1 ;;< 0x18 + .ImageBase resd 1 ;;< 0x1c + .SectionAlignment resd 1 ;;< 0x20 + .FileAlignment resd 1 ;;< 0x24 + .MajorOperatingSystemVersion resw 1 ;;< 0x28 + .MinorOperatingSystemVersion resw 1 ;;< 0x2a + .MajorImageVersion resw 1 ;;< 0x2c + .MinorImageVersion resw 1 ;;< 0x2e + .MajorSubsystemVersion resw 1 ;;< 0x30 + .MinorSubsystemVersion resw 1 ;;< 0x32 + .Win32VersionValue resd 1 ;;< 0x34 + .SizeOfImage resd 1 ;;< 0x38 + .SizeOfHeaders resd 1 ;;< 0x3c + .CheckSum resd 1 ;;< 0x40 + .Subsystem resw 1 ;;< 0x44 + .DllCharacteristics resw 1 ;;< 0x46 + .SizeOfStackReserve resd 1 ;;< 0x48 + .SizeOfStackCommit resd 1 ;;< 0x4c + .SizeOfHeapReserve resd 1 ;;< 0x50 + .SizeOfHeapCommit resd 1 ;;< 0x54 + .LoaderFlags resd 1 ;;< 0x58 + .NumberOfRvaAndSizes resd 1 ;;< 0x5c + .DataDirectory resb IMAGE_DATA_DIRECTORY_size * IMAGE_NUMBEROF_DIRECTORY_ENTRIES ;;< 0x60; 0x10*8 = 0x80 +endstruc +AssertCompileSize(IMAGE_OPTIONAL_HEADER32, 0xe0); + +struc IMAGE_OPTIONAL_HEADER64 + .Magic resw 1 ;;< 0x00 + .MajorLinkerVersion resb 1 ;;< 0x02 + .MinorLinkerVersion resb 1 ;;< 0x03 + .SizeOfCode resd 1 ;;< 0x04 + .SizeOfInitializedData resd 1 ;;< 0x08 + .SizeOfUninitializedData resd 1 ;;< 0x0c + .AddressOfEntryPoint resd 1 ;;< 0x10 + .BaseOfCode resd 1 ;;< 0x14 + .ImageBase resq 1 ;;< 0x18 + .SectionAlignment resd 1 ;;< 0x20 + .FileAlignment resd 1 ;;< 0x24 + .MajorOperatingSystemVersion resw 1 ;;< 0x28 + .MinorOperatingSystemVersion resw 1 ;;< 0x2a + .MajorImageVersion resw 1 ;;< 0x2c + .MinorImageVersion resw 1 ;;< 0x2e + .MajorSubsystemVersion resw 1 ;;< 0x30 + .MinorSubsystemVersion resw 1 ;;< 0x32 + .Win32VersionValue resd 1 ;;< 0x34 + .SizeOfImage resd 1 ;;< 0x38 + .SizeOfHeaders resd 1 ;;< 0x3c + .CheckSum resd 1 ;;< 0x40 + .Subsystem resw 1 ;;< 0x44 + .DllCharacteristics resw 1 ;;< 0x46 + .SizeOfStackReserve resq 1 ;;< 0x48 + .SizeOfStackCommit resq 1 ;;< 0x50 + .SizeOfHeapReserve resq 1 ;;< 0x58 + .SizeOfHeapCommit resq 1 ;;< 0x60 + .LoaderFlags resd 1 ;;< 0x68 + .NumberOfRvaAndSizes resd 1 ;;< 0x6c + .DataDirectory resb IMAGE_DATA_DIRECTORY_size * IMAGE_NUMBEROF_DIRECTORY_ENTRIES ;;< 0x70; 0x10*8 = 0x80 +endstruc ; size: 0xf0 +AssertCompileSize(IMAGE_OPTIONAL_HEADER64, 0xf0); + + +struc IMAGE_NT_HEADERS32 + .Signature resd 1 ;;< 0x00 + .FileHeader resb IMAGE_FILE_HEADER_size ; ;;< 0x04 + .OptionalHeader resb IMAGE_OPTIONAL_HEADER32_size ;;< 0x18 +endstruc ; size: 0xf8 +AssertCompileSize(IMAGE_NT_HEADERS32, 0xf8); +AssertCompileMemberOffset(IMAGE_NT_HEADERS32, FileHeader, 4); +AssertCompileMemberOffset(IMAGE_NT_HEADERS32, OptionalHeader, 24); + +struc IMAGE_NT_HEADERS64 + .Signature resd 1 ;;< 0x00 + .FileHeader resb IMAGE_FILE_HEADER_size ;;< 0x04 + .OptionalHeader resb IMAGE_OPTIONAL_HEADER64_size ;;< 0x18 +endstruc ; size: 0x108 +AssertCompileSize(IMAGE_NT_HEADERS64, 0x108); +AssertCompileMemberOffset(IMAGE_NT_HEADERS64, FileHeader, 4); +AssertCompileMemberOffset(IMAGE_NT_HEADERS64, OptionalHeader, 24); + + +struc IMAGE_SECTION_HEADER + .Name resb IMAGE_SIZEOF_SHORT_NAME + .Misc.VirtualSize resd 1 + .VirtualAddress resd 1 + .SizeOfRawData resd 1 + .PointerToRawData resd 1 + .PointerToRelocations resd 1 + .PointerToLinenumbers resd 1 + .NumberOfRelocations resw 1 + .NumberOfLinenumbers resw 1 + .Characteristics resd 1 +endstruc +%define IMAGE_SECTION_HEADER.Misc.PhysicalAddress IMAGE_SECTION_HEADER.Misc.VirtualSize + + +struc IMAGE_BASE_RELOCATION + .VirtualAddress resd 1 + .SizeOfBlock resd 1 +endstruc + + +struc IMAGE_EXPORT_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .Name resd 1 + .Base resd 1 + .NumberOfFunctions resd 1 + .NumberOfNames resd 1 + .AddressOfFunctions resd 1 + .AddressOfNames resd 1 + .AddressOfNameOrdinals resd 1 +endstruc + + +struc IMAGE_IMPORT_DESCRIPTOR + .u.Characteristics resd 1 + .TimeDateStamp resd 1 + .ForwarderChain resd 1 + .Name resd 1 + .FirstThunk resd 1 +endstruc +%define IMAGE_IMPORT_DESCRIPTOR.u.OriginalFirstThunk IMAGE_IMPORT_DESCRIPTOR.u.Characteristics + +struc IMAGE_IMPORT_BY_NAME + .Hint resw 1 + .Name resb 1 +endstruc + + +struc IMAGE_THUNK_DATA64 + .u1.ForwarderString resq 1 +endstruc +%define IMAGE_THUNK_DATA64.u1.Function IMAGE_THUNK_DATA64.u1.ForwarderString +%define IMAGE_THUNK_DATA64.u1.Ordinal IMAGE_THUNK_DATA64.u1.ForwarderString +%define IMAGE_THUNK_DATA64.u1.AddressOfData IMAGE_THUNK_DATA64.u1.ForwarderString + +struc IMAGE_THUNK_DATA32 + .u1.ForwarderString resd 1 +endstruc +%define IMAGE_THUNK_DATA32.u1.Function IMAGE_THUNK_DATA32.u1.ForwarderString +%define IMAGE_THUNK_DATA32.u1.Ordinal IMAGE_THUNK_DATA32.u1.ForwarderString +%define IMAGE_THUNK_DATA32.u1.AddressOfData IMAGE_THUNK_DATA32.u1.ForwarderString + + +struc IMAGE_LOAD_CONFIG_DIRECTORY32 + .Size resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .GlobalFlagsClear resd 1 + .GlobalFlagsSet resd 1 + .CriticalSectionDefaultTimeout resd 1 + .DeCommitFreeBlockThreshold resd 1 + .DeCommitTotalFreeThreshold resd 1 + .LockPrefixTable resd 1 + .MaximumAllocationSize resd 1 + .VirtualMemoryThreshold resd 1 + .ProcessHeapFlags resd 1 + .ProcessAffinityMask resd 1 + .CSDVersion resw 1 + .Reserved1 resw 1 + .EditList resd 1 + .SecurityCookie resd 1 + .SEHandlerTable resd 1 + .SEHandlerCount resd 1 +endstruc + +struc IMAGE_LOAD_CONFIG_DIRECTORY64 + .Size resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .GlobalFlagsClear resd 1 + .GlobalFlagsSet resd 1 + .CriticalSectionDefaultTimeout resd 1 + .DeCommitFreeBlockThreshold resq 1 + .DeCommitTotalFreeThreshold resq 1 + .LockPrefixTable resq 1 + .MaximumAllocationSize resq 1 + .VirtualMemoryThreshold resq 1 + .ProcessAffinityMask resq 1 + .ProcessHeapFlags resd 1 + .CSDVersion resw 1 + .Reserved1 resw 1 + .EditList resq 1 + .SecurityCookie resq 1 + .SEHandlerTable resq 1 + .SEHandlerCount resq 1 +endstruc + + +struc IMAGE_DEBUG_DIRECTORY + .Characteristics resd 1 + .TimeDateStamp resd 1 + .MajorVersion resw 1 + .MinorVersion resw 1 + .Type resd 1 + .SizeOfData resd 1 + .AddressOfRawData resd 1 + .PointerToRawData resd 1 +endstruc + +struc IMAGE_DEBUG_MISC + .DataType resd 1 + .Length resd 1 + .Unicode resb 1 + .Reserved resb 3 + .Data resb 1 +endstruc + + +struc WIN_CERTIFICATE + .dwLength resd 1 + .wRevision resw 1 + .wCertificateType resw 1 + .bCertificate resb 8 +endstruc + +;; The header of a .DBG file (NT4). +struc IMAGE_SEPARATE_DEBUG_HEADER + .Signature resw 1 ;;< 0x00 + .Flags resw 1 ;;< 0x02 + .Machine resw 1 ;;< 0x04 + .Characteristics resw 1 ;;< 0x06 + .TimeDateStamp resd 1 ;;< 0x08 + .CheckSum resd 1 ;;< 0x0c + .ImageBase resd 1 ;;< 0x10 + .SizeOfImage resd 1 ;;< 0x14 + .NumberOfSections resd 1 ;;< 0x18 + .ExportedNamesSize resd 1 ;;< 0x1c + .DebugDirectorySize resd 1 ;;< 0x20 + .SectionAlignment resd 1 ;;< 0x24 + .Reserved resd 2 ;;< 0x28 +endstruc ; size: 0x30 +AssertCompileSize(IMAGE_SEPARATE_DEBUG_HEADER, 0x30); + + +struc IMAGE_COFF_SYMBOLS_HEADER + .NumberOfSymbols resd 1 + .LvaToFirstSymbol resd 1 + .NumberOfLinenumbers resd 1 + .LvaToFirstLinenumber resd 1 + .RvaToFirstByteOfCode resd 1 + .RvaToLastByteOfCode resd 1 + .RvaToFirstByteOfData resd 1 + .RvaToLastByteOfData resd 1 +endstruc +AssertCompileSize(IMAGE_COFF_SYMBOLS_HEADER, 0x20); + + +struc IMAGE_LINENUMBER + .Type.VirtualAddress resd 1 + .Linenumber resw 1 +endstruc +AssertCompileSize(IMAGE_LINENUMBER, 6); +%define IMAGE_LINENUMBER.Type.SymbolTableIndex IMAGE_LINENUMBER.Type.VirtualAddress + + +;;#pragma pack(2) +;;struc IMAGE_SYMBOL +;;{ +;; union +;; { +;; uint8_t ShortName[8]; +;; struct +;; { +;; .Short resd 1 +;; .Long resd 1 +;; } Name; +;; uint32_t LongName[2]; +;; } N; +;; +;; .Value resd 1 +;; int16_t SectionNumber; +;; .Type resw 1 +;; .StorageClass resb 1 +;; .NumberOfAuxSymbols resb 1 +;;} IMAGE_SYMBOL; +;;#pragma pack() +;;AssertCompileSize(IMAGE_SYMBOL, IMAGE_SIZE_OF_SYMBOL); +;; +;; +;;#pragma pack(2) +;;typedef struct IMAGE_AUX_SYMBOL_TOKEN_DEF +;;{ +;; .bAuxType resb 1 +;; .bReserved resb 1 +;; .SymbolTableIndex resd 1 +;; uint8_t rgbReserved[12]; +;;} IMAGE_AUX_SYMBOL_TOKEN_DEF; +;;#pragma pack() +;;AssertCompileSize(IMAGE_AUX_SYMBOL_TOKEN_DEF, IMAGE_SIZE_OF_SYMBOL); +;; +;; +;;#pragma pack(1) +;;typedef union _IMAGE_AUX_SYMBOL +;;{ +;; struct +;; { +;; .TagIndex resd 1 +;; union +;; { +;; struct +;; { +;; .Linenumber resw 1 +;; .Size resw 1 +;; } LnSz; +;; } Misc; +;; union +;; { +;; struct +;; { +;; .PointerToLinenumber resd 1 +;; .PointerToNextFunction resd 1 +;; } Function; +;; struct +;; { +;; uint16_t Dimension[4]; +;; } Array; +;; } FcnAry; +;; .TvIndex resw 1 +;; } Sym; +;; +;; struct +;; { +;; uint8_t Name[IMAGE_SIZE_OF_SYMBOL]; +;; } File; +;; +;; struct +;; { +;; .Length resd 1 +;; .NumberOfRelocations resw 1 +;; .NumberOfLinenumbers resw 1 +;; .CheckSum resd 1 +;; .Number resw 1 +;; .Selection resb 1 +;; .bReserved resb 1 +;; .HighNumber resw 1 +;; } Section; +;; +;; IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef; +;; struct +;; { +;; .crc resd 1 +;; uint8_t rgbReserved[14]; +;; } CRC; +;;} IMAGE_AUX_SYMBOL; +;;#pragma pack() +;;AssertCompileSize(IMAGE_AUX_SYMBOL, IMAGE_SIZE_OF_SYMBOL); +;; +;; +;; +;;struc IMAGE_SYMBOL_EX +;;{ +;; union +;; { +;; uint8_t ShortName[8]; +;; struct +;; { +;; .Short resd 1 +;; .Long resd 1 +;; } Name; +;; uint32_t LongName[2]; +;; } N; +;; +;; .Value resd 1 +;; int32_t SectionNumber; /* The difference from IMAGE_SYMBOL +;; .Type resw 1 +;; .StorageClass resb 1 +;; .NumberOfAuxSymbols resb 1 +;;} IMAGE_SYMBOL_EX; +;;AssertCompileSize(IMAGE_SYMBOL_EX, IMAGE_SIZE_OF_SYMBOL_EX); +;; +;; +;;typedef union _IMAGE_AUX_SYMBOL_EX +;;{ +;; struct +;; { +;; .WeakDefaultSymIndex resd 1 +;; .WeakSearchType resd 1 +;; uint8_t rgbReserved[12]; +;; } Sym; +;; +;; struct +;; { +;; uint8_t Name[IMAGE_SIZE_OF_SYMBOL_EX]; +;; } File; +;; +;; struct +;; { +;; .Length resd 1 +;; .NumberOfRelocations resw 1 +;; .NumberOfLinenumbers resw 1 +;; .CheckSum resd 1 +;; .Number resw 1 +;; .Selection resb 1 +;; .bReserved resb 1 +;; .HighNumber resw 1 +;; uint8_t rgbReserved[2]; +;; } Section; +;; +;; IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef; +;; +;; struct +;; { +;; .crc resd 1 +;; uint8_t rgbReserved[16]; +;; } CRC; +;;} IMAGE_AUX_SYMBOL_EX; +;;AssertCompileSize(IMAGE_AUX_SYMBOL_EX, IMAGE_SIZE_OF_SYMBOL_EX); + +%endif + diff --git a/include/iprt/formats/xar.h b/include/iprt/formats/xar.h new file mode 100644 index 00000000..5cb1eaa1 --- /dev/null +++ b/include/iprt/formats/xar.h @@ -0,0 +1,68 @@ +/** @file + * IPRT - Extensible Archiver (XAR) format. + */ + +/* + * 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 ___iprt_formats_xar_h +#define ___iprt_formats_xar_h + + +#pragma pack(4) /* Misdesigned header, not 8-byte aligned size. */ +typedef struct XARHEADER +{ + /** The magic number 'xar!' (XAR_HEADER_MAGIC). */ + uint32_t u32Magic; + /** The size of this header structure. */ + uint16_t cbHeader; + /** The header version structure. */ + uint16_t uVersion; + /** The size of the compressed table of content (TOC). */ + uint64_t cbTocCompressed; + /** The size of the table of context (TOC) when not compressed. */ + uint64_t cbTocUncompressed; + /** Which cryptographic hash function is used (XAR_HASH_XXX). */ + uint32_t uHashFunction; +} XARHEADER; +#pragma pack() +/** Pointer to a XAR header. */ +typedef XARHEADER *PXARHEADER; +/** Pointer to a const XAR header. */ +typedef XARHEADER const *PCXARHEADER; + +/** XAR magic value (on disk endian). */ +#define XAR_HEADER_MAGIC RT_H2LE_U32(RT_MAKE_U32_FROM_U8('x', 'a', 'r', '!')) +/** The current header version value (host endian). */ +#define XAR_HEADER_VERSION 1 + +/** @name XAR hashing functions. + * @{ */ +#define XAR_HASH_NONE 0 +#define XAR_HASH_SHA1 1 +#define XAR_HASH_MD5 2 +#define XAR_HASH_MAX 2 +/** @} */ + + +#endif + diff --git a/include/iprt/fs.h b/include/iprt/fs.h index 6ad2d2c5..3055bf4b 100644 --- a/include/iprt/fs.h +++ b/include/iprt/fs.h @@ -3,7 +3,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; @@ -93,6 +93,11 @@ RT_C_DECLS_BEGIN /** Other executable (S_IXOTH). */ #define RTFS_UNIX_IXOTH 0000001U +/** All UNIX access permission bits (0777). */ +#define RTFS_UNIX_ALL_ACCESS_PERMS 0000777U +/** All UNIX permission bits, including set id and sticky bits. */ +#define RTFS_UNIX_ALL_PERMS 0007777U + /** Named pipe (fifo) (S_IFIFO). */ #define RTFS_TYPE_FIFO 0010000U /** Character device (S_IFCHR). */ @@ -216,6 +221,7 @@ typedef enum RTFSTYPE RTFSTYPE_SYSFS, RTFSTYPE_PROC, RTFSTYPE_OCFS2, + RTFSTYPE_BTRFS, /* Windows: */ /** New Technology File System. */ diff --git a/include/iprt/getopt.h b/include/iprt/getopt.h index bf976cef..042a6e5c 100644 --- a/include/iprt/getopt.h +++ b/include/iprt/getopt.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2011 Oracle Corporation + * Copyright (C) 2007-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; @@ -69,12 +69,20 @@ RT_C_DECLS_BEGIN /** The value must be a valid IPv4 address. * (Not a name, but 4 values in the 0..255 range with dots separating them). */ #define RTGETOPT_REQ_IPV4ADDR 10 -#if 0 /** The value must be a valid IPv4 CIDR. * As with RTGETOPT_REQ_IPV4ADDR, no name. - * @todo Mix CIDR with types.h or/and net.h first and find a way to make the - * mask optional like with ifconfig. See RTCidrStrToIPv4. */ + */ #define RTGETOPT_REQ_IPV4CIDR 11 +#if 0 +/* take placers */ +/** The value must be a valid IPv6 addr + * @todo: Add types and parsing routines in (iprt/net.h) + */ +#define RTGETOPT_REQ_IPV6ADDR 12 +/** The value must be a valid IPv6 CIDR + * @todo: Add types and parsing routines in (iprt/net.h) + */ +#define RTGETOPT_REQ_IPV6CIDR 13 #endif /** The value must be a valid ethernet MAC address. */ #define RTGETOPT_REQ_MACADDR 14 @@ -163,6 +171,12 @@ typedef union RTGETOPTUNION #ifdef ___iprt_net_h /** A RTGETOPT_REQ_IPV4ADDR option argument. */ RTNETADDRIPV4 IPv4Addr; + /** A RTGETOPT_REQ_IPV4CIDR option argument. */ + struct + { + RTNETADDRIPV4 IPv4Network; + RTNETADDRIPV4 IPv4Netmask; + } CidrIPv4; #endif /** A RTGETOPT_REQ_MACADDR option argument. */ RTMAC MacAddr; @@ -379,7 +393,7 @@ RTDECL(RTEXITCODE) RTGetOptPrintError(int ch, PCRTGETOPTUNION pValueUnion); * This is useful for converting a response file or similar to an argument * vector that can be used with RTGetOptInit(). * - * This function aims at following the bourn shell string quoting rules. + * This function aims at following the bourne shell string quoting rules. * * @returns IPRT status code. * diff --git a/include/iprt/handletable.h b/include/iprt/handletable.h index 0ade7412..c26f7871 100644 --- a/include/iprt/handletable.h +++ b/include/iprt/handletable.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2008 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; @@ -89,12 +89,15 @@ typedef FNRTHANDLETABLEDELETE *PFNRTHANDLETABLEDELETE; * * Setting this means you will have to use the WithCtx functions to do the * handle management. */ -#define RTHANDLETABLE_FLAGS_CONTEXT RT_BIT_32(0) -/** Whether the handle table should take care of the serialization. +#define RTHANDLETABLE_FLAGS_CONTEXT RT_BIT_32(0) +/** Whether the handle table should take care of the serialization (IRQ unsafe). * If not specified the caller will have to take care of that. */ -#define RTHANDLETABLE_FLAGS_LOCKED RT_BIT_32(1) +#define RTHANDLETABLE_FLAGS_LOCKED RT_BIT_32(1) +/** Like RTHANDLETABLE_FLAGS_LOCKED, except it's IRQ safe. + * A side-effect is that callbacks may be called with IRQs disabled. */ +#define RTHANDLETABLE_FLAGS_LOCKED_IRQ_SAFE RT_BIT_32(2) /** The mask of valid flags. */ -#define RTHANDLETABLE_FLAGS_MASK UINT32_C(0x00000003) +#define RTHANDLETABLE_FLAGS_MASK UINT32_C(0x00000007) /** @} */ diff --git a/include/iprt/heap.h b/include/iprt/heap.h index f9e0c524..4151fac0 100644 --- a/include/iprt/heap.h +++ b/include/iprt/heap.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2009 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/include/iprt/http.h b/include/iprt/http.h new file mode 100644 index 00000000..dc4a8cc5 --- /dev/null +++ b/include/iprt/http.h @@ -0,0 +1,169 @@ +/* $Id: http.h $ */ +/** @file + * IPRT - Simple HTTP Communication API. + */ + +/* + * Copyright (C) 2012-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 ___iprt_http_h +#define ___iprt_http_h + +#include + +RT_C_DECLS_BEGIN + +/** @defgroup grp_rt_http RTHttp - Simple HTTP API + * @ingroup grp_rt + * @{ + */ + +/** @todo the following three definitions may move the iprt/types.h later. */ +/** RTHTTP interface handle. */ +typedef R3PTRTYPE(struct RTHTTPINTERNAL *) RTHTTP; +/** Pointer to a RTHTTP interface handle. */ +typedef RTHTTP *PRTHTTP; +/** Nil RTHTTP interface handle. */ +#define NIL_RTHTTP ((RTHTTP)0) + + +/** + * Creates a HTTP interface handle. + * + * @returns iprt status code. + * + * @param phHttp Where to store the HTTP handle. + */ +RTR3DECL(int) RTHttpCreate(PRTHTTP phHttp); + +/** + * Destroys a HTTP interface handle. + * + * @param hHttp Handle to the HTTP interface. + */ +RTR3DECL(void) RTHttpDestroy(RTHTTP hHttp); + +/** + * Perform a simple blocking HTTP request. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle. + * @param pcszUrl URL. + * @param ppszResponse HTTP response. It is guaranteed that this string is + * '\0'-terminated. + */ +RTR3DECL(int) RTHttpGet(RTHTTP hHttp, const char *pcszUrl, char **ppszResponse); + +/** + * Perform a simple blocking HTTP request, writing the output to a file. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle. + * @param pszUrl URL. + * @param pszDstFile The destination file name. + */ +RTR3DECL(int) RTHttpGetFile(RTHTTP hHttp, const char *pszUrl, const char *pszDstFile); + +/** + * Abort a pending HTTP request. A blocking RTHttpGet() call will return with + * VERR_HTTP_ABORTED. It may take some time (current cURL implementation needs + * up to 1 second) before the request is aborted. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle. + */ +RTR3DECL(int) RTHttpAbort(RTHTTP hHttp); + +/** + * Tells the HTTP interface to use the system proxy configuration. + * + * @returns iprt status code. + * @param hHttp HTTP interface handle. + */ +RTR3DECL(int) RTHttpUseSystemProxySettings(RTHTTP hHttp); + +/** + * Specify proxy settings. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle. + * @param pcszProxy URL of the proxy + * @param uPort port number of the proxy, use 0 for not specifying a port. + * @param pcszUser username, pass NULL for no authentication + * @param pcszPwd password, pass NULL for no authentication + */ +RTR3DECL(int) RTHttpSetProxy(RTHTTP hHttp, const char *pcszProxyUrl, uint32_t uPort, + const char *pcszProxyUser, const char *pcszProxyPwd); + +/** + * Set custom headers. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle. + * @param cHeaders number of custom headers. + * @param pcszHeaders array of headers in form "foo: bar". + */ +RTR3DECL(int) RTHttpSetHeaders(RTHTTP hHttp, size_t cHeaders, const char * const *papszHeaders); + +/** + * Set a custom certification authority file, containing root certificates. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle. + * @param pcszCAFile File name containing root certificates. + */ +RTR3DECL(int) RTHttpSetCAFile(RTHTTP hHttp, const char *pcszCAFile); + + +/** + * Determine the digest (fingerprint) of a certificate. Allocate memory for + * storing the SHA1 fingerprint as well as the SHA512 fingerprint. This + * memory has to be freed by RTMemFree(). + * + * @todo Move this function to somewhere else. + * + * @returns iprt status code. + * + * @param hHttp HTTP interface handle (ignored). + * @param pcszCert The certificate in PEM format. + * @param cbCert Size of the certificate. + * @param pabSha1 Where to store the pointer to the SHA1 fingerprint. + * @param pcbSha1 Where to store the size of the SHA1 fingerprint. + * @param pabSha512 Where to store the pointer to the SHA512 fingerprint. + * @param pcbSha512 Where to store the size of the SHA512 fingerprint. + */ +RTR3DECL(int) RTHttpCertDigest(RTHTTP hHttp, char *pcszCert, size_t cbCert, + uint8_t **pabSha1, size_t *pcbSha1, + uint8_t **pabSha512, size_t *pcbSha512); + + +/** @} */ + +RT_C_DECLS_END + +#endif + diff --git a/include/iprt/initterm.h b/include/iprt/initterm.h index 9fff94fc..1853fbb3 100644 --- a/include/iprt/initterm.h +++ b/include/iprt/initterm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2009 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; @@ -46,6 +46,10 @@ RT_C_DECLS_BEGIN #define RTR3INIT_FLAGS_SUPLIB RT_BIT(0) /** Initializing IPRT from a DLL. */ #define RTR3INIT_FLAGS_DLL RT_BIT(1) +/** We are sharing a process space, so we need to behave. */ +#define RTR3INIT_FLAGS_UNOBTRUSIVE RT_BIT(2) +/** The caller ensures that the argument bector is UTF-8. */ +#define RTR3INIT_FLAGS_UTF8_ARGV RT_BIT(3) /** @} */ /** @name RTR3InitEx version @@ -103,6 +107,11 @@ RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char *** */ RTR3DECL(void) RTR3Term(void); +/** + * Are we running in unobtrusive mode? + * @returns true/false. + */ +RTR3DECL(bool) RTR3InitIsUnobtrusive(void); #endif /* IN_RING3 */ diff --git a/include/iprt/isofs.h b/include/iprt/isofs.h index c7774cd9..e6f3356e 100644 --- a/include/iprt/isofs.h +++ b/include/iprt/isofs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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/include/iprt/ldr.h b/include/iprt/ldr.h index 9e036d83..80c432de 100644 --- a/include/iprt/ldr.h +++ b/include/iprt/ldr.h @@ -3,7 +3,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; @@ -50,6 +50,87 @@ typedef RTLDRADDR const *PCRTLDRADDR; #define NIL_RTLDRADDR RTLDRADDR_MAX +/** + * Loader module format. + */ +typedef enum RTLDRFMT +{ + /** The usual invalid 0 format. */ + RTLDRFMT_INVALID = 0, + /** The native OS loader. */ + RTLDRFMT_NATIVE, + /** The AOUT loader. */ + RTLDRFMT_AOUT, + /** The ELF loader. */ + RTLDRFMT_ELF, + /** The LX loader. */ + RTLDRFMT_LX, + /** The Mach-O loader. */ + RTLDRFMT_MACHO, + /** The PE loader. */ + RTLDRFMT_PE, + /** The end of the valid format values (exclusive). */ + RTLDRFMT_END, + /** Hack to blow the type up to 32-bit. */ + RTLDRFMT_32BIT_HACK = 0x7fffffff +} RTLDRFMT; + + +/** + * Loader module type. + */ +typedef enum RTLDRTYPE +{ + /** The usual invalid 0 type. */ + RTLDRTYPE_INVALID = 0, + /** Object file. */ + RTLDRTYPE_OBJECT, + /** Executable module, fixed load address. */ + RTLDRTYPE_EXECUTABLE_FIXED, + /** Executable module, relocatable, non-fixed load address. */ + RTLDRTYPE_EXECUTABLE_RELOCATABLE, + /** Executable module, position independent code, non-fixed load address. */ + RTLDRTYPE_EXECUTABLE_PIC, + /** Shared library, fixed load address. + * Typically a system library. */ + RTLDRTYPE_SHARED_LIBRARY_FIXED, + /** Shared library, relocatable, non-fixed load address. */ + RTLDRTYPE_SHARED_LIBRARY_RELOCATABLE, + /** Shared library, position independent code, non-fixed load address. */ + RTLDRTYPE_SHARED_LIBRARY_PIC, + /** DLL that contains no code or data only imports and exports. (Chiefly OS/2.) */ + RTLDRTYPE_FORWARDER_DLL, + /** Core or dump. */ + RTLDRTYPE_CORE, + /** Debug module (debug info with empty code & data segments). */ + RTLDRTYPE_DEBUG_INFO, + /** The end of the valid types values (exclusive). */ + RTLDRTYPE_END, + /** Hack to blow the type up to 32-bit. */ + RTLDRTYPE_32BIT_HACK = 0x7fffffff +} RTLDRTYPE; + + +/** + * Loader endian indicator. + */ +typedef enum RTLDRENDIAN +{ + /** The usual invalid endian. */ + RTLDRENDIAN_INVALID, + /** Little endian. */ + RTLDRENDIAN_LITTLE, + /** Bit endian. */ + RTLDRENDIAN_BIG, + /** Endianness doesn't have a meaning in the context. */ + RTLDRENDIAN_NA, + /** The end of the valid endian values (exclusive). */ + RTLDRENDIAN_END, + /** Hack to blow the type up to 32-bit. */ + RTLDRENDIAN_32BIT_HACK = 0x7fffffff +} RTLDRENDIAN; + + /** * Gets the default file suffix for DLL/SO/DYLIB/whatever. * @@ -113,10 +194,35 @@ RTDECL(int) RTLdrLoadEx(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fF /** Symbols defined in this library will be made available for symbol * resolution of subsequently loaded libraries. */ #define RTLDRLOAD_FLAGS_GLOBAL RT_BIT_32(0) +/** Do not unload the library upon RTLdrClose. (For system libs.) */ +#define RTLDRLOAD_FLAGS_NO_UNLOAD RT_BIT_32(1) /** The mask of valid flag bits. */ -#define RTLDRLOAD_FLAGS_VALID_MASK UINT32_C(0x00000001) +#define RTLDRLOAD_FLAGS_VALID_MASK UINT32_C(0x00000003) /** @} */ +/** + * Loads a dynamic load library (/shared object) image file residing in one of + * the default system library locations. + * + * Only the system library locations are searched. No suffix is required. + * + * @returns iprt status code. + * @param pszFilename Image filename. No path. + * @param fNoUnload Do not unload the library when RTLdrClose is called. + * @param phLdrMod Where to store the handle to the loaded module. + */ +RTDECL(int) RTLdrLoadSystem(const char *pszFilename, bool fNoUnload, PRTLDRMOD phLdrMod); + +/** + * Combines RTLdrLoadSystem and RTLdrGetSymbol, with fNoUnload set to true. + * + * @returns The symbol value, NULL on failure. (If you care for a less boolean + * status, go thru the necessary API calls yourself.) + * @param pszFilename Image filename. No path. + * @param pszSymbol Symbol name. + */ +RTDECL(void *) RTLdrGetSystemSymbol(const char *pszFilename, const char *pszSymbol); + /** * Loads a dynamic load library (/shared object) image file residing in the * RTPathAppPrivateArch() directory. @@ -129,6 +235,16 @@ RTDECL(int) RTLdrLoadEx(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fF */ RTDECL(int) RTLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod); +/** + * Gets the native module handle for a module loaded by RTLdrLoad, RTLdrLoadEx, + * RTLdrLoadSystem, or RTLdrLoadAppPriv. + * + * @returns Native handle on success, ~(uintptr_t)0 on failure. + * @param hLdrMod The loader module handle. + */ +RTDECL(uintptr_t) RTLdrGetNativeHandle(RTLDRMOD hLdrMod); + + /** * Image architecuture specifier for RTLdrOpenEx. */ @@ -151,12 +267,21 @@ typedef enum RTLDRARCH /** Pointer to a RTLDRARCH. */ typedef RTLDRARCH *PRTLDRARCH; +/** @name RTLDR_O_XXX - RTLdrOpen flags. + * @{ */ +/** Open for debugging or introspection reasons. + * This will skip a few of the stricter validations when loading images. */ +#define RTLDR_O_FOR_DEBUG RT_BIT_32(0) +/** Mask of valid flags. */ +#define RTLDR_O_VALID_MASK UINT32_C(0x00000001) +/** @} */ + /** * Open a binary image file, extended version. * * @returns iprt status code. * @param pszFilename Image filename. - * @param fFlags Reserved, MBZ. + * @param fFlags Valid RTLDR_O_XXX combination. * @param enmArch CPU architecture specifier for the image to be loaded. * @param phLdrMod Where to store the handle to the loader module. */ @@ -166,53 +291,72 @@ RTDECL(int) RTLdrOpen(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArc * Opens a binary image file using kLdr. * * @returns iprt status code. - * @param pszFilename Image filename. - * @param phLdrMod Where to store the handle to the loaded module. - * @param fFlags Reserved, MBZ. + * @param pszFilename Image filename. + * @param phLdrMod Where to store the handle to the loaded module. + * @param fFlags Valid RTLDR_O_XXX combination. * @param enmArch CPU architecture specifier for the image to be loaded. * @remark Primarily for testing the loader. */ RTDECL(int) RTLdrOpenkLdr(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod); + /** - * What to expect and do with the bits passed to RTLdrOpenBits(). + * Called to read @a cb bytes at @a off into @a pvBuf. + * + * @returns IPRT status code + * @param pvBuf The output buffer. + * @param cb The number of bytes to read. + * @param off Where to start reading. + * @param pvUser The user parameter. */ -typedef enum RTLDROPENBITS -{ - /** The usual invalid 0 entry. */ - RTLDROPENBITS_INVALID = 0, - /** The bits are readonly and will never be changed. */ - RTLDROPENBITS_READONLY, - /** The bits are going to be changed and the loader will have to duplicate them - * when opening the image. */ - RTLDROPENBITS_WRITABLE, - /** The bits are both the source and destination for the loader operation. - * This means that the loader may have to duplicate them prior to changing them. */ - RTLDROPENBITS_SRC_AND_DST, - /** The end of the valid enums. This entry marks the - * first invalid entry.. */ - RTLDROPENBITS_END, - RTLDROPENBITS_32BIT_HACK = 0x7fffffff -} RTLDROPENBITS; - -/** - * Open a binary image from in-memory bits. +typedef DECLCALLBACK(int) FNRTLDRRDRMEMREAD(void *pvBuf, size_t cb, size_t off, void *pvUser); +/** Pointer to a RTLdrOpenInMemory reader callback. */ +typedef FNRTLDRRDRMEMREAD *PFNRTLDRRDRMEMREAD; + +/** + * Called to when the module is unloaded (or done loading) to release resources + * associated with it (@a pvUser). * - * @returns iprt status code. - * @param pvBits The start of the raw-image. - * @param cbBits The size of the raw-image. - * @param enmBits What to expect from the pvBits. - * @param pszLogName What to call the raw-image when logging. - * For RTLdrLoad and RTLdrOpen the filename is used for this. - * @param phLdrMod Where to store the handle to the loader module. + * @returns IPRT status code + * @param pvUser The user parameter. */ -RTDECL(int) RTLdrOpenBits(const void *pvBits, size_t cbBits, RTLDROPENBITS enmBits, const char *pszLogName, PRTLDRMOD phLdrMod); +typedef DECLCALLBACK(void) FNRTLDRRDRMEMDTOR(void *pvUser); +/** Pointer to a RTLdrOpenInMemory destructor callback. */ +typedef FNRTLDRRDRMEMDTOR *PFNRTLDRRDRMEMDTOR; + +/** + * Open a in-memory image or an image with a custom reader callback. + * + * @returns IPRT status code. + * @param pszName The image name. + * @param fFlags Valid RTLDR_O_XXX combination. + * @param enmArch CPU architecture specifier for the image to be loaded. + * @param cbImage The size of the image (fake file). + * @param pfnRead The read function. If NULL is passed in, a default + * reader function is provided that assumes @a pvUser + * points to the raw image bits, at least @a cbImage of + * valid memory. + * @param pfnDtor The destructor function. If NULL is passed, a default + * destructor will be provided that passes @a pvUser to + * RTMemFree. + * @param pvUser The user argument or, if any of the callbacks are NULL, + * a pointer to a memory block. + * @param phLdrMod Where to return the module handle. + * + * @remarks With the exception of invalid @a pfnDtor and/or @a pvUser + * parameters, the pfnDtor methods (or the default one if NULL) will + * always be invoked. The destruction of pvUser is entirely in the + * hands of this method once it's called. + */ +RTDECL(int) RTLdrOpenInMemory(const char *pszName, uint32_t fFlags, RTLDRARCH enmArch, size_t cbImage, + PFNRTLDRRDRMEMREAD pfnRead, PFNRTLDRRDRMEMDTOR pfnDtor, void *pvUser, + PRTLDRMOD phLdrMod); /** * Closes a loader module handle. * * The handle can be obtained using any of the RTLdrLoad(), RTLdrOpen() - * and RTLdrOpenBits() functions. + * and RTLdrOpenInMemory() functions. * * @returns iprt status code. * @param hLdrMod The loader module handle. @@ -250,14 +394,28 @@ RTDECL(int) RTLdrGetSymbol(RTLDRMOD hLdrMod, const char *pszSymbol, void **ppvVa RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress, const char *pszSymbol, PRTLDRADDR pValue); + +/** + * Gets the address of a named exported function. + * + * Same as RTLdrGetSymbol, but skips the status code and pointer to return + * variable stuff. + * + * @returns Pointer to the function if found, NULL if not. + * @param hLdrMod The loader module handle. + * @param pszSymbol Function name. + */ +RTDECL(PFNRT) RTLdrGetFunction(RTLDRMOD hLdrMod, const char *pszSymbol); + /** * Gets the size of the loaded image. - * This is only supported for modules which has been opened using RTLdrOpen() and RTLdrOpenBits(). + * + * This is not necessarily available for images that has been loaded using + * RTLdrLoad(). * * @returns image size (in bytes). - * @returns ~(size_t)0 on if not opened by RTLdrOpen(). + * @returns ~(size_t)0 on if not available. * @param hLdrMod Handle to the loader module. - * @remark Not supported for RTLdrLoad() images. */ RTDECL(size_t) RTLdrSize(RTLDRMOD hLdrMod); @@ -341,7 +499,9 @@ RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBi /** @name RTLdrEnumSymbols flags. * @{ */ /** Returns ALL kinds of symbols. The default is to only return public/exported symbols. */ -#define RTLDR_ENUM_SYMBOL_FLAGS_ALL RT_BIT(1) +#define RTLDR_ENUM_SYMBOL_FLAGS_ALL RT_BIT(1) +/** Ignore forwarders (for use with RTLDR_ENUM_SYMBOL_FLAGS_ALL). */ +#define RTLDR_ENUM_SYMBOL_FLAGS_NO_FWD RT_BIT(2) /** @} */ @@ -358,8 +518,18 @@ typedef enum RTLDRDBGINFOTYPE RTLDRDBGINFOTYPE_STABS, /** Debug With Arbitrary Record Format (DWARF). */ RTLDRDBGINFOTYPE_DWARF, + /** Debug With Arbitrary Record Format (DWARF), in external file (DWO). */ + RTLDRDBGINFOTYPE_DWARF_DWO, /** Microsoft Codeview debug info. */ RTLDRDBGINFOTYPE_CODEVIEW, + /** Microsoft Codeview debug info, in external v2.0+ program database (PDB). */ + RTLDRDBGINFOTYPE_CODEVIEW_PDB20, + /** Microsoft Codeview debug info, in external v7.0+ program database (PDB). */ + RTLDRDBGINFOTYPE_CODEVIEW_PDB70, + /** Microsoft Codeview debug info, in external file (DBG). */ + RTLDRDBGINFOTYPE_CODEVIEW_DBG, + /** Microsoft COFF debug info. */ + RTLDRDBGINFOTYPE_COFF, /** Watcom debug info. */ RTLDRDBGINFOTYPE_WATCOM, /** IBM High Level Language debug info.. */ @@ -370,6 +540,96 @@ typedef enum RTLDRDBGINFOTYPE RTLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff } RTLDRDBGINFOTYPE; + +/** + * Debug info details for the enumeration callback. + */ +typedef struct RTLDRDBGINFO +{ + /** The kind of debug info. */ + RTLDRDBGINFOTYPE enmType; + /** The debug info ordinal number / id. */ + uint32_t iDbgInfo; + /** The file offset *if* this type has one specific location in the executable + * image file. This is -1 if there isn't any specific file location. */ + RTFOFF offFile; + /** The link address of the debug info if it's loadable. NIL_RTLDRADDR if not + * loadable*/ + RTLDRADDR LinkAddress; + /** The size of the debug information. -1 is used if this isn't applicable.*/ + RTLDRADDR cb; + /** This is set if the debug information is found in an external file. NULL + * if no external file involved. + * @note Putting it outside the union to allow lazy callback implementation. */ + const char *pszExtFile; + /** Type (enmType) specific information. */ + union + { + /** RTLDRDBGINFOTYPE_DWARF */ + struct + { + /** The section name. */ + const char *pszSection; + } Dwarf; + + /** RTLDRDBGINFOTYPE_DWARF_DWO */ + struct + { + /** The CRC32 of the external file. */ + uint32_t uCrc32; + } Dwo; + + /** RTLDRDBGINFOTYPE_CODEVIEW, RTLDRDBGINFOTYPE_COFF */ + struct + { + /** The PE image size. */ + uint32_t cbImage; + /** The timestamp. */ + uint32_t uTimestamp; + /** The major version from the entry. */ + uint32_t uMajorVer; + /** The minor version from the entry. */ + uint32_t uMinorVer; + } Cv, Coff; + + /** RTLDRDBGINFOTYPE_CODEVIEW_DBG */ + struct + { + /** The PE image size. */ + uint32_t cbImage; + /** The timestamp. */ + uint32_t uTimestamp; + } Dbg; + + /** RTLDRDBGINFOTYPE_CODEVIEW_PDB20*/ + struct + { + /** The PE image size. */ + uint32_t cbImage; + /** The timestamp. */ + uint32_t uTimestamp; + /** The PDB age. */ + uint32_t uAge; + } Pdb20; + + /** RTLDRDBGINFOTYPE_CODEVIEW_PDB70 */ + struct + { + /** The PE image size. */ + uint32_t cbImage; + /** The PDB age. */ + uint32_t uAge; + /** The UUID. */ + RTUUID Uuid; + } Pdb70; + } u; +} RTLDRDBGINFO; +/** Pointer to debug info details. */ +typedef RTLDRDBGINFO *PRTLDRDBGINFO; +/** Pointer to read only debug info details. */ +typedef RTLDRDBGINFO const *PCRTLDRDBGINFO; + + /** * Debug info enumerator callback. * @@ -377,30 +637,10 @@ typedef enum RTLDRDBGINFOTYPE * will cause RTLdrEnumDbgInfo to immediately return with that status. * * @param hLdrMod The module handle. - * @param iDbgInfo The debug info ordinal number / id. - * @param enmType The debug info type. - * @param iMajorVer The major version number of the debug info format. - * -1 if unknow - implies invalid iMinorVer. - * @param iMinorVer The minor version number of the debug info format. - * -1 when iMajorVer is -1. - * @param pszPartNm The name of the debug info part, NULL if not - * applicable. - * @param offFile The file offset *if* this type has one specific - * location in the executable image file. This is -1 - * if there isn't any specific file location. - * @param LinkAddress The link address of the debug info if it's - * loadable. NIL_RTLDRADDR if not loadable. - * @param cb The size of the debug information. -1 is used if - * this isn't applicable. - * @param pszExtFile This points to the name of an external file - * containing the debug info. This is NULL if there - * isn't any external file. + * @param pDbgInfo Pointer to a read only structure with the details. * @param pvUser The user parameter specified to RTLdrEnumDbgInfo. */ -typedef DECLCALLBACK(int) FNRTLDRENUMDBG(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType, - uint16_t iMajorVer, uint16_t iMinorVer, const char *pszPartNm, - RTFOFF offFile, RTLDRADDR LinkAddress, RTLDRADDR cb, - const char *pszExtFile, void *pvUser); +typedef DECLCALLBACK(int) FNRTLDRENUMDBG(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser); /** Pointer to a debug info enumerator callback. */ typedef FNRTLDRENUMDBG *PFNRTLDRENUMDBG; @@ -424,8 +664,8 @@ RTDECL(int) RTLdrEnumDbgInfo(RTLDRMOD hLdrMod, const void *pvBits, PFNRTLDRENUMD */ typedef struct RTLDRSEG { - /** The segment name. (Might not be zero terminated!) */ - const char *pchName; + /** The segment name. Always set to something. */ + const char *pszName; /** The length of the segment name. */ uint32_t cchName; /** The flat selector to use for the segment (i.e. data/code). @@ -551,6 +791,43 @@ RTDECL(int) RTLdrSegOffsetToRva(RTLDRMOD hLdrMod, uint32_t iSeg, RTLDRADDR offSe */ RTDECL(int) RTLdrRvaToSegOffset(RTLDRMOD hLdrMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg); +/** + * Gets the image format. + * + * @returns Valid image format on success. RTLDRFMT_INVALID on invalid handle or + * other errors. + * @param hLdrMod The module handle. + */ +RTDECL(RTLDRFMT) RTLdrGetFormat(RTLDRMOD hLdrMod); + +/** + * Gets the image type. + * + * @returns Valid image type value on success. RTLDRTYPE_INVALID on + * invalid handle or other errors. + * @param hLdrMod The module handle. + */ +RTDECL(RTLDRTYPE) RTLdrGetType(RTLDRMOD hLdrMod); + +/** + * Gets the image endian-ness. + * + * @returns Valid image endian value on success. RTLDRENDIAN_INVALID on invalid + * handle or other errors. + * @param hLdrMod The module handle. + */ +RTDECL(RTLDRENDIAN) RTLdrGetEndian(RTLDRMOD hLdrMod); + +/** + * Gets the image endian-ness. + * + * @returns Valid image architecture value on success. + * RTLDRARCH_INVALID on invalid handle or other errors. + * @param hLdrMod The module handle. + */ +RTDECL(RTLDRARCH) RTLdrGetArch(RTLDRMOD hLdrMod); + + RT_C_DECLS_END /** @} */ diff --git a/include/iprt/ldrlazy.h b/include/iprt/ldrlazy.h new file mode 100644 index 00000000..addfa36e --- /dev/null +++ b/include/iprt/ldrlazy.h @@ -0,0 +1,102 @@ +/** @file + * IPRT - Lazy share library linking (2nd try). + */ + +/* + * 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 ___iprt_ldrlazy_h +#define ___iprt_ldrlazy_h + +#include + +/** @defgroup grp_rt_ldrlazy Lazy shared library linking. + * @ingroup grp_rt + * + * + * @{ + */ + + +/** + * Defines a module for use in lazy resolving. + * + * @param a_Mod The module name (C name). + * @param a_pszFile The file to tell RTLdrLoad to load. + */ +#define RTLDRLAZY_MODULE(a_Mod, a_pszFile) \ + RTLDRLAZY_MODULE_EX(a_Mod, a_pszFile, RTLdrLoad) + +/** + * Defines a module for use in lazy resolving. + * + * @param a_Mod The module name (C name). + * @param a_pszFile The file to tell RTLdrLoad to load. + * @param a_pfnLoadIt Function to call for loading the DLL, replacing + * RTLdrLoad. + */ +#define RTLDRLAZY_MODULE_EX(a_Mod, a_pszFile, a_pfnLoadIt) \ + static bool rtLdrLazy_##a_Mod##_Resolve(const char *pszName, void **ppvSymbol) \ + { \ + static RTLDRMOD volatile s_hMod = NIL_RTLDRMOD; \ + static bool volatile s_fLoaded = false; \ + RTLDRMOD hMod; \ + int rc; \ + if (!s_fLoaded) \ + { \ + rc = a_pfnLoadIt(a_pszFile, &hMod); \ + s_hMod = RT_SUCCESS(rc) ? hMod : NIL_RTLDRMOD; \ + s_fLoaded = true; \ + if (RT_FAILURE(rc)) \ + return false; \ + } \ + hMod = s_hMod; \ + if (hMod == NIL_RTLDRMOD) \ + return false; \ + rc = RTLdrGetSymbol(hMod, pszName, ppvSymbol); \ + return RT_SUCCESS(rc); \ + } + + + +/** Function name mangler for preventing collision with system prototypes. */ +#define RTLDRLAZY_FUNC_NAME(a_Mod, a_Name) a_Mod##__##a_Name + +/** + * Defines a function that should be lazily resolved. + */ +#define RTLDRLAZY_FUNC(a_Mod, a_RetType, a_CallConv, a_Name, a_ParamDecl, a_ParamNames, a_ErrRet) \ + DECLINLINE(a_RetType) RTLDRLAZY_FUNC_NAME(a_Mod, a_Name) a_ParamDecl \ + { \ + static a_RetType (a_CallConv * s_pfn) a_ParamDecl; \ + if (!s_pfn) \ + { \ + if (!rtLdrLazy_##a_Mod##_Resolve(#a_Name, (void **)&s_pfn)) \ + return a_ErrRet; \ + } \ + return s_pfn a_ParamNames; \ + } + + +/** @} */ + +#endif + diff --git a/include/iprt/linux/sysfs.h b/include/iprt/linux/sysfs.h index 27010af4..c4862799 100644 --- a/include/iprt/linux/sysfs.h +++ b/include/iprt/linux/sysfs.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; diff --git a/include/iprt/list.h b/include/iprt/list.h index 1a4a4bc0..929b3180 100644 --- a/include/iprt/list.h +++ b/include/iprt/list.h @@ -3,7 +3,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; @@ -183,6 +183,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListNodeIsDummy(pList, pNode, Type, Member) \ ( (pNode) == RT_FROM_MEMBER((pList), Type, Member) ) +/** @copydoc RTListNodeIsDummy */ +#define RTListNodeIsDummyCpp(pList, pNode, Type, Member) \ + ( (pNode) == RT_FROM_CPP_MEMBER((pList), Type, Member) ) /** * Checks if a list is empty. @@ -205,6 +208,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListNodeGetNext(pCurNode, Type, Member) \ RT_FROM_MEMBER((pCurNode)->pNext, Type, Member) +/** @copydoc RTListNodeGetNext */ +#define RTListNodeGetNextCpp(pCurNode, Type, Member) \ + RT_FROM_CPP_MEMBER((pCurNode)->pNext, Type, Member) /** * Returns the previous node in the list. @@ -217,6 +223,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListNodeGetPrev(pCurNode, Type, Member) \ RT_FROM_MEMBER((pCurNode)->pPrev, Type, Member) +/** @copydoc RTListNodeGetPrev */ +#define RTListNodeGetPrevCpp(pCurNode, Type, Member) \ + RT_FROM_CPP_MEMBER((pCurNode)->pPrev, Type, Member) /** * Returns the first element in the list (checks for empty list). @@ -230,6 +239,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListGetFirst(pList, Type, Member) \ (!RTListIsEmpty(pList) ? RTListNodeGetNext(pList, Type, Member) : NULL) +/** @copydoc RTListGetFirst */ +#define RTListGetFirstCpp(pList, Type, Member) \ + (!RTListIsEmpty(pList) ? RTListNodeGetNextCpp(pList, Type, Member) : NULL) /** * Returns the last element in the list (checks for empty list). @@ -243,6 +255,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListGetLast(pList, Type, Member) \ (!RTListIsEmpty(pList) ? RTListNodeGetPrev(pList, Type, Member) : NULL) +/** @copydoc RTListGetLast */ +#define RTListGetLastCpp(pList, Type, Member) \ + (!RTListIsEmpty(pList) ? RTListNodeGetPrevCpp(pList, Type, Member) : NULL) /** * Returns the next node in the list or NULL if the end has been reached. @@ -256,6 +271,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListGetNext(pList, pCurNode, Type, Member) \ ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL ) +/** @copydoc RTListGetNext */ +#define RTListGetNextCpp(pList, pCurNode, Type, Member) \ + ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_CPP_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL ) /** * Returns the previous node in the list or NULL if the start has been reached. @@ -269,6 +287,9 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) */ #define RTListGetPrev(pList, pCurNode, Type, Member) \ ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL ) +/** @copydoc RTListGetPrev */ +#define RTListGetPrevCpp(pList, pCurNode, Type, Member) \ + ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_CPP_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL ) /** * Enumerate the list in head to tail order. @@ -282,6 +303,11 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) for (pIterator = RTListNodeGetNext(pList, Type, Member); \ !RTListNodeIsDummy(pList, pIterator, Type, Member); \ pIterator = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) ) +/** @copydoc RTListForEach */ +#define RTListForEachCpp(pList, pIterator, Type, Member) \ + for (pIterator = RTListNodeGetNextCpp(pList, Type, Member); \ + !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \ + pIterator = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member) ) /** @@ -301,6 +327,13 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) !RTListNodeIsDummy(pList, pIterator, Type, Member); \ pIterator = pIterNext, \ pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) ) +/** @copydoc RTListForEachSafe */ +#define RTListForEachSafeCpp(pList, pIterator, pIterNext, Type, Member) \ + for (pIterator = RTListNodeGetNextCpp(pList, Type, Member), \ + pIterNext = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member); \ + !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \ + pIterator = pIterNext, \ + pIterNext = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member) ) /** @@ -315,6 +348,11 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) for (pIterator = RTListNodeGetPrev(pList, Type, Member); \ !RTListNodeIsDummy(pList, pIterator, Type, Member); \ pIterator = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) ) +/** @copydoc RTListForEachReverse */ +#define RTListForEachReverseCpp(pList, pIterator, Type, Member) \ + for (pIterator = RTListNodeGetPrevCpp(pList, Type, Member); \ + !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \ + pIterator = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member) ) /** @@ -333,6 +371,13 @@ DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode) !RTListNodeIsDummy(pList, pIterator, Type, Member); \ pIterator = pIterPrev, \ pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) ) +/** @copydoc RTListForEachReverseSafe */ +#define RTListForEachReverseSafeCpp(pList, pIterator, pIterPrev, Type, Member) \ + for (pIterator = RTListNodeGetPrevCpp(pList, Type, Member), \ + pIterPrev = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member); \ + !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \ + pIterator = pIterPrev, \ + pIterPrev = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member) ) /** diff --git a/include/iprt/localipc.h b/include/iprt/localipc.h index 0a887e42..37196626 100644 --- a/include/iprt/localipc.h +++ b/include/iprt/localipc.h @@ -3,7 +3,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; @@ -75,7 +75,7 @@ RTDECL(int) RTLocalIpcServerCreate(PRTLOCALIPCSERVER phServer, const char *pszNa /** @name RTLocalIpcServerCreate flags * @{ */ -/** The server can handle multiple session. */ +/** The server can handle multiple sessions. */ #define RTLOCALIPC_FLAGS_MULTI_SESSION RT_BIT_32(0) /** The mask of valid flags. */ #define RTLOCALIPC_FLAGS_VALID_MASK UINT32_C(0x00000001) @@ -150,7 +150,7 @@ RTDECL(int) RTLocalIpcSessionClose(RTLOCALIPCSESSION hSession); * @param hSession The session handle. * @param pvBuffer Where to store the data. * @param cbBuffer If pcbRead is non-NULL this indicates the maximum number of - * bytes to read. If pcbRead is NULL the this is the exact number + * bytes to read. If pcbRead is NULL then this is the exact number * of bytes to read. * @param pcbRead Optional argument for indicating a partial read and returning * the number of bytes actually read. @@ -188,7 +188,7 @@ RTDECL(int) RTLocalIpcSessionWrite(RTLOCALIPCSESSION hSession, const void *pvBuf RTDECL(int) RTLocalIpcSessionFlush(RTLOCALIPCSESSION hSession); /** - * Wait for data to become read for reading or for the + * Wait for data to become ready for reading or for the * session to be disconnected. * * @returns IPRT status code. diff --git a/include/iprt/lockvalidator.h b/include/iprt/lockvalidator.h index 7e0f08c1..b088b1e9 100644 --- a/include/iprt/lockvalidator.h +++ b/include/iprt/lockvalidator.h @@ -3,7 +3,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; @@ -102,9 +102,6 @@ AssertCompileSize(RTLOCKVALSRCPOS, HC_ARCH_BITS == 32 ? 16 : 32); #define RTLOCKVALSRCPOS_INIT_POS_NO_ID() \ RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, (uintptr_t)ASMReturnAddress()) -/** Pointer to a record of one ownership share. */ -typedef struct RTLOCKVALRECSHRD *PRTLOCKVALRECSHRD; - /** * Lock validator record core. @@ -568,6 +565,7 @@ RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, */ RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock, bool fSignaller, bool fEnabled, const char *pszNameFmt, ...); + /** * Initialize a lock validator record for a shared lock. * @@ -592,6 +590,7 @@ RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS */ RTDECL(void) RTLockValidatorRecSharedInitV(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock, bool fSignaller, bool fEnabled, const char *pszNameFmt, va_list va); + /** * Uninitialize a lock validator record previously initialized by * RTLockValidatorRecSharedInit. @@ -600,6 +599,68 @@ RTDECL(void) RTLockValidatorRecSharedInitV(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLAS */ RTDECL(void) RTLockValidatorRecSharedDelete(PRTLOCKVALRECSHRD pRec); +/** + * Create and initialize a lock validator record for a shared lock. + * + * Use RTLockValidatorRecSharedDestroy to deinitialize and destroy the returned + * record. + * + * @returns IPRT status code. + * @param ppRec Where to return the record pointer. + * @param hClass The class (no reference consumed). If NIL, the + * no lock order validation will be performed on + * this lock. + * @param uSubClass The sub-class. This is used to define lock + * order inside the same class. If you don't know, + * then pass RTLOCKVAL_SUB_CLASS_NONE. + * @param pvLock The lock handle or address. + * @param fSignaller Set if event semaphore signaller logic should be + * applied to this record, clear if read-write + * semaphore logic should be used. + * @param fEnabled Pass @c false to explicitly disable lock + * validation, otherwise @c true. + * @param pszNameFmt Name format string for the lock validator, + * optional (NULL). Max length is 32 bytes. + * @param ... Format string arguments. + */ +RTDECL(int) RTLockValidatorRecSharedCreate(PRTLOCKVALRECSHRD *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, + void *pvLock, bool fSignaller, bool fEnabled, const char *pszNameFmt, ...); + +/** + * Create and initialize a lock validator record for a shared lock. + * + * Use RTLockValidatorRecSharedDestroy to deinitialize and destroy the returned + * record. + * + * @returns IPRT status code. + * @param ppRec Where to return the record pointer. + * @param hClass The class (no reference consumed). If NIL, the + * no lock order validation will be performed on + * this lock. + * @param uSubClass The sub-class. This is used to define lock + * order inside the same class. If you don't know, + * then pass RTLOCKVAL_SUB_CLASS_NONE. + * @param pvLock The lock handle or address. + * @param fSignaller Set if event semaphore signaller logic should be + * applied to this record, clear if read-write + * semaphore logic should be used. + * @param fEnabled Pass @c false to explicitly disable lock + * validation, otherwise @c true. + * @param pszNameFmt Name format string for the lock validator, + * optional (NULL). Max length is 32 bytes. + * @param va Format string arguments. + */ +RTDECL(int) RTLockValidatorRecSharedCreateV(PRTLOCKVALRECSHRD *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, + void *pvLock, bool fSignaller, bool fEnabled, const char *pszNameFmt, va_list va); + +/** + * Deinitialize and destroy a record created by RTLockValidatorRecSharedCreate. + * + * @param ppRec Pointer to the record pointer. Will be set to + * NULL. + */ +RTDECL(void) RTLockValidatorRecSharedDestroy(PRTLOCKVALRECSHRD *ppRec); + /** * Sets the sub-class of the record. * diff --git a/include/iprt/log.h b/include/iprt/log.h index cce17079..427eebc8 100644 --- a/include/iprt/log.h +++ b/include/iprt/log.h @@ -3,7 +3,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; @@ -705,6 +705,22 @@ RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, c do { Log((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); Log(a); } while (0) #endif +/** @def Log4Func + * Level 4 logging inside C/C++ functions. + * + * Prepends the given log message with the function name followed by a + * semicolon and space. + * + * @param a Log message in format ("string\n" [, args]). + */ +#ifdef LOG_USE_C99 +# define Log4Func(a) \ + _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a ) +#else +# define Log4Func(a) \ + do { Log((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); Log(a); } while (0) +#endif + /** @def LogThisFunc * The same as LogFunc but for class functions (methods): the resulting log * line is additionally prepended with a hex value of |this| pointer. diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h index cc8b4ec6..58c9e94d 100644 --- a/include/iprt/mangling.h +++ b/include/iprt/mangling.h @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2011-2012 Oracle Corporation + * Copyright (C) 2011-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; @@ -55,8 +55,22 @@ # define ASMAtomicReadU64_EndProc RT_MANGLER(ASMAtomicReadU64_EndProc) # define ASMAtomicUoReadU64 RT_MANGLER(ASMAtomicUoReadU64) /* not-some-systems... */ # define ASMAtomicUoReadU64_EndProc RT_MANGLER(ASMAtomicUoReadU64_EndProc) +# define ASMAtomicUoAndU64 RT_MANGLER(ASMAtomicUoAndU64) /* not-some-systems... */ +# define ASMAtomicUoAndU64_EndProc RT_MANGLER(ASMAtomicUoAndU64_EndProc) +# define ASMAtomicUoAndU32 RT_MANGLER(ASMAtomicUoAndU32) /* not-some-systems... */ +# define ASMAtomicUoAndU32_EndProc RT_MANGLER(ASMAtomicUoAndU32_EndProc) +# define ASMAtomicUoOrU64 RT_MANGLER(ASMAtomicUoOrU64) /* not-some-systems... */ +# define ASMAtomicUoOrU64_EndProc RT_MANGLER(ASMAtomicUoOrU64_EndProc) +# define ASMAtomicUoOrU32 RT_MANGLER(ASMAtomicUoOrU32) /* not-some-systems... */ +# define ASMAtomicUoOrU32_EndProc RT_MANGLER(ASMAtomicUoOrU32_EndProc) # define ASMAtomicXchgU64 RT_MANGLER(ASMAtomicXchgU64) /* not-some-systems... */ # define ASMAtomicXchgU64_EndProc RT_MANGLER(ASMAtomicXchgU64_EndProc) +# define ASMRdMsrEx RT_MANGLER(ASMRdMsrEx) +# define ASMRdMsrEx_EndProc RT_MANGLER(ASMRdMsrEx_EndProc) +# define ASMWrMsrEx RT_MANGLER(ASMWrMsrEx) +# define ASMWrMsrEx_EndProc RT_MANGLER(ASMWrMsrEx_EndProc) +# define ASMCpuIdExSlow RT_MANGLER(ASMCpuIdExSlow) +# define ASMCpuIdExSlow_EndProc RT_MANGLER(ASMCpuIdExSlow_EndProc) # define RTAssertAreQuiet RT_MANGLER(RTAssertAreQuiet) # define RTAssertMayPanic RT_MANGLER(RTAssertMayPanic) # define RTAssertMsg1 RT_MANGLER(RTAssertMsg1) @@ -324,6 +338,25 @@ # define RTCritSectSetSubClass RT_MANGLER(RTCritSectSetSubClass) # define RTCritSectTryEnter RT_MANGLER(RTCritSectTryEnter) # define RTCritSectTryEnterDebug RT_MANGLER(RTCritSectTryEnterDebug) +# define RTCritSectRwDelete RT_MANGLER(RTCritSectRwDelete) +# define RTCritSectRwEnterExcl RT_MANGLER(RTCritSectRwEnterExcl) +# define RTCritSectRwEnterExclDebug RT_MANGLER(RTCritSectRwEnterExclDebug) +# define RTCritSectRwEnterShared RT_MANGLER(RTCritSectRwEnterShared) +# define RTCritSectRwEnterSharedDebug RT_MANGLER(RTCritSectRwEnterSharedDebug) +# define RTCritSectRwGetReadCount RT_MANGLER(RTCritSectRwGetReadCount) +# define RTCritSectRwGetWriteRecursion RT_MANGLER(RTCritSectRwGetWriteRecursion) +# define RTCritSectRwGetWriterReadRecursion RT_MANGLER(RTCritSectRwGetWriterReadRecursion) +# define RTCritSectRwInit RT_MANGLER(RTCritSectRwInit) +# define RTCritSectRwInitEx RT_MANGLER(RTCritSectRwInitEx) +# define RTCritSectRwIsReadOwner RT_MANGLER(RTCritSectRwIsReadOwner) +# define RTCritSectRwIsWriteOwner RT_MANGLER(RTCritSectRwIsWriteOwner) +# define RTCritSectRwLeaveExcl RT_MANGLER(RTCritSectRwLeaveExcl) +# define RTCritSectRwLeaveShared RT_MANGLER(RTCritSectRwLeaveShared) +# define RTCritSectRwSetSubClass RT_MANGLER(RTCritSectRwSetSubClass) +# define RTCritSectRwTryEnterExcl RT_MANGLER(RTCritSectRwTryEnterExcl) +# define RTCritSectRwTryEnterExclDebug RT_MANGLER(RTCritSectRwTryEnterExclDebug) +# define RTCritSectRwTryEnterShared RT_MANGLER(RTCritSectRwTryEnterShared) +# define RTCritSectRwTryEnterSharedDebug RT_MANGLER(RTCritSectRwTryEnterSharedDebug) # define RTDbgAsCreate RT_MANGLER(RTDbgAsCreate) # define RTDbgAsCreateF RT_MANGLER(RTDbgAsCreateF) # define RTDbgAsCreateV RT_MANGLER(RTDbgAsCreateV) @@ -332,6 +365,7 @@ # define RTDbgAsLineAdd RT_MANGLER(RTDbgAsLineAdd) # define RTDbgAsLineByAddr RT_MANGLER(RTDbgAsLineByAddr) # define RTDbgAsLineByAddrA RT_MANGLER(RTDbgAsLineByAddrA) +# define RTDbgAsLockExcl RT_MANGLER(RTDbgAsLockExcl) # define RTDbgAsModuleByAddr RT_MANGLER(RTDbgAsModuleByAddr) # define RTDbgAsModuleByIndex RT_MANGLER(RTDbgAsModuleByIndex) # define RTDbgAsModuleByName RT_MANGLER(RTDbgAsModuleByName) @@ -349,15 +383,35 @@ # define RTDbgAsSymbolByAddrA RT_MANGLER(RTDbgAsSymbolByAddrA) # define RTDbgAsSymbolByName RT_MANGLER(RTDbgAsSymbolByName) # define RTDbgAsSymbolByNameA RT_MANGLER(RTDbgAsSymbolByNameA) +# define RTDbgAsUnlockExcl RT_MANGLER(RTDbgAsUnlockExcl) +# define RTDbgCfgCreate RT_MANGLER(RTDbgCfgCreate) +# define RTDbgCfgRetain RT_MANGLER(RTDbgCfgRetain) +# define RTDbgCfgRelease RT_MANGLER(RTDbgCfgRelease) +# define RTDbgCfgChangeString RT_MANGLER(RTDbgCfgChangeString) +# define RTDbgCfgChangeUInt RT_MANGLER(RTDbgCfgChangeUInt) +# define RTDbgCfgQueryString RT_MANGLER(RTDbgCfgQueryString) +# define RTDbgCfgQueryUInt RT_MANGLER(RTDbgCfgQueryUInt) +# define RTDbgCfgOpenDbg RT_MANGLER(RTDbgCfgOpenDbg) +# define RTDbgCfgOpenDsymBundle RT_MANGLER(RTDbgCfgOpenDsymBundle) +# define RTDbgCfgOpenDwo RT_MANGLER(RTDbgCfgOpenDwo) +# define RTDbgCfgOpenPdb70 RT_MANGLER(RTDbgCfgOpenPdb70) +# define RTDbgCfgOpenPdb20 RT_MANGLER(RTDbgCfgOpenPdb20) +# define RTDbgCfgOpenPeImage RT_MANGLER(RTDbgCfgOpenPeImage) +# define RTDbgCfgSetLogCallback RT_MANGLER(RTDbgCfgSetLogCallback) # define RTDbgLineAlloc RT_MANGLER(RTDbgLineAlloc) # define RTDbgLineDup RT_MANGLER(RTDbgLineDup) # define RTDbgLineFree RT_MANGLER(RTDbgLineFree) # define RTDbgModCreate RT_MANGLER(RTDbgModCreate) -# define RTDbgModCreateDeferred RT_MANGLER(RTDbgModCreateDeferred) +# define RTDbgModCreateFromDbg RT_MANGLER(RTDbgModCreateFromDbg) +# define RTDbgModCreateFromDwo RT_MANGLER(RTDbgModCreateFromDwo) # define RTDbgModCreateFromImage RT_MANGLER(RTDbgModCreateFromImage) # define RTDbgModCreateFromMap RT_MANGLER(RTDbgModCreateFromMap) +# define RTDbgModCreateFromPdb RT_MANGLER(RTDbgModCreateFromPdb) +# define RTDbgModCreateFromPeImage RT_MANGLER(RTDbgModCreateFromPeImage) # define RTDbgModGetTag RT_MANGLER(RTDbgModGetTag) # define RTDbgModImageSize RT_MANGLER(RTDbgModImageSize) +# define RTDbgModIsDeferred RT_MANGLER(RTDbgModIsDeferred) +# define RTDbgModIsExports RT_MANGLER(RTDbgModIsExports) # define RTDbgModLineAdd RT_MANGLER(RTDbgModLineAdd) # define RTDbgModLineByAddr RT_MANGLER(RTDbgModLineByAddr) # define RTDbgModLineByAddrA RT_MANGLER(RTDbgModLineByAddrA) @@ -365,7 +419,11 @@ # define RTDbgModLineByOrdinalA RT_MANGLER(RTDbgModLineByOrdinalA) # define RTDbgModLineCount RT_MANGLER(RTDbgModLineCount) # define RTDbgModName RT_MANGLER(RTDbgModName) +# define RTDbgModDebugFile RT_MANGLER(RTDbgModDebugFile) +# define RTDbgModImageFile RT_MANGLER(RTDbgModImageFile) +# define RTDbgModImageFileUsed RT_MANGLER(RTDbgModImageFileUsed) # define RTDbgModRelease RT_MANGLER(RTDbgModRelease) +# define RTDbgModRemoveAll RT_MANGLER(RTDbgModRemoveAll) # define RTDbgModRetain RT_MANGLER(RTDbgModRetain) # define RTDbgModRvaToSegOff RT_MANGLER(RTDbgModRvaToSegOff) # define RTDbgModSegmentAdd RT_MANGLER(RTDbgModSegmentAdd) @@ -391,12 +449,16 @@ # define RTDirCreateTemp RT_MANGLER(RTDirCreateTemp) # define RTDirCreateTempSecure RT_MANGLER(RTDirCreateTempSecure) # define RTDirCreateUniqueNumbered RT_MANGLER(RTDirCreateUniqueNumbered) +# define RTDirEntryIsStdDotLink RT_MANGLER(RTDirEntryIsStdDotLink) +# define RTDirEntryExIsStdDotLink RT_MANGLER(RTDirEntryExIsStdDotLink) # define RTDirExists RT_MANGLER(RTDirExists) # define RTDirFlush RT_MANGLER(RTDirFlush) # define RTDirFlushParent RT_MANGLER(RTDirFlushParent) # define RTDirOpen RT_MANGLER(RTDirOpen) # define RTDirOpenFiltered RT_MANGLER(RTDirOpenFiltered) # define RTDirQueryInfo RT_MANGLER(RTDirQueryInfo) +# define RTDirQueryUnknownType RT_MANGLER(RTDirQueryUnknownType) +# define RTDirQueryUnknownTypeEx RT_MANGLER(RTDirQueryUnknownTypeEx) # define RTDirRead RT_MANGLER(RTDirRead) # define RTDirReadEx RT_MANGLER(RTDirReadEx) # define RTDirRemove RT_MANGLER(RTDirRemove) @@ -430,17 +492,27 @@ # define RTEnvDestroy RT_MANGLER(RTEnvDestroy) # define RTEnvDupEx RT_MANGLER(RTEnvDupEx) # define RTEnvExist RT_MANGLER(RTEnvExist) +# define RTEnvExistsBad RT_MANGLER(RTEnvExistsBad) +# define RTEnvExistsUtf8 RT_MANGLER(RTEnvExistsUtf8) # define RTEnvExistEx RT_MANGLER(RTEnvExistEx) # define RTEnvFreeUtf16Block RT_MANGLER(RTEnvFreeUtf16Block) # define RTEnvGet RT_MANGLER(RTEnvGet) +# define RTEnvGetBad RT_MANGLER(RTEnvGetBad) +# define RTEnvGetUtf8 RT_MANGLER(RTEnvGetUtf8) # define RTEnvGetEx RT_MANGLER(RTEnvGetEx) # define RTEnvGetExecEnvP RT_MANGLER(RTEnvGetExecEnvP) # define RTEnvPut RT_MANGLER(RTEnvPut) +# define RTEnvPutBad RT_MANGLER(RTEnvPutBad) +# define RTEnvPutUtf8 RT_MANGLER(RTEnvPutUtf8) # define RTEnvPutEx RT_MANGLER(RTEnvPutEx) # define RTEnvQueryUtf16Block RT_MANGLER(RTEnvQueryUtf16Block) # define RTEnvSet RT_MANGLER(RTEnvSet) +# define RTEnvSetBad RT_MANGLER(RTEnvSetBad) +# define RTEnvSetUtf8 RT_MANGLER(RTEnvSetUtf8) # define RTEnvSetEx RT_MANGLER(RTEnvSetEx) # define RTEnvUnset RT_MANGLER(RTEnvUnset) +# define RTEnvUnsetBad RT_MANGLER(RTEnvUnsetBad) +# define RTEnvUnsetUtf8 RT_MANGLER(RTEnvUnsetUtf8) # define RTEnvUnsetEx RT_MANGLER(RTEnvUnsetEx) # define RTErrCOMGet RT_MANGLER(RTErrCOMGet) # define RTErrConvertFromErrno RT_MANGLER(RTErrConvertFromErrno) @@ -490,6 +562,8 @@ # define RTFileIoCtl RT_MANGLER(RTFileIoCtl) # define RTFileIsValid RT_MANGLER(RTFileIsValid) # define RTFileLock RT_MANGLER(RTFileLock) +# define RTFileModeToFlags RT_MANGLER(RTFileModeToFlags) +# define RTFileModeToFlagsEx RT_MANGLER(RTFileModeToFlagsEx) # define RTFileMove RT_MANGLER(RTFileMove) # define RTFileOpen RT_MANGLER(RTFileOpen) # define RTFileOpenBitBucket RT_MANGLER(RTFileOpenBitBucket) @@ -509,8 +583,11 @@ # define RTFileSeek RT_MANGLER(RTFileSeek) # define RTFileSetForceFlags RT_MANGLER(RTFileSetForceFlags) # define RTFileSetMode RT_MANGLER(RTFileSetMode) +# define RTFileSetOwner RT_MANGLER(RTFileSetOwner) # define RTFileSetSize RT_MANGLER(RTFileSetSize) # define RTFileSetTimes RT_MANGLER(RTFileSetTimes) +# define RTFileSgReadAt RT_MANGLER(RTFileSgReadAt) +# define RTFileSgWriteAt RT_MANGLER(RTFileSgWriteAt) # define RTFileTell RT_MANGLER(RTFileTell) # define RTFileToNative RT_MANGLER(RTFileToNative) # define RTFileUnlock RT_MANGLER(RTFileUnlock) @@ -558,6 +635,8 @@ # define RTHeapSimpleInit RT_MANGLER(RTHeapSimpleInit) # define RTHeapSimpleRelocate RT_MANGLER(RTHeapSimpleRelocate) # define RTHeapSimpleSize RT_MANGLER(RTHeapSimpleSize) +# define RTHttpGetFile RT_MANGLER(RTHttpGetFile) +# define RTHttpUseSystemProxySettings RT_MANGLER(RTHttpUseSystemProxySettings) # define RTIsoFsClose RT_MANGLER(RTIsoFsClose) # define RTIsoFsExtractFile RT_MANGLER(RTIsoFsExtractFile) # define RTIsoFsGetFileInfo RT_MANGLER(RTIsoFsGetFileInfo) @@ -574,17 +653,26 @@ # define RTLdrEnumDbgInfo RT_MANGLER(RTLdrEnumDbgInfo) # define RTLdrEnumSegments RT_MANGLER(RTLdrEnumSegments) # define RTLdrEnumSymbols RT_MANGLER(RTLdrEnumSymbols) +# define RTLdrGetArch RT_MANGLER(RTLdrGetArch) # define RTLdrGetBits RT_MANGLER(RTLdrGetBits) +# define RTLdrGetEndian RT_MANGLER(RTLdrGetEndian) +# define RTLdrGetFormat RT_MANGLER(RTLdrGetFormat) +# define RTLdrGetFunction RT_MANGLER(RTLdrGetFunction) +# define RTLdrGetNativeHandle RT_MANGLER(RTLdrGetNativeHandle) # define RTLdrGetSuff RT_MANGLER(RTLdrGetSuff) # define RTLdrGetSymbol RT_MANGLER(RTLdrGetSymbol) # define RTLdrGetSymbolEx RT_MANGLER(RTLdrGetSymbolEx) +# define RTLdrGetSystemSymbol RT_MANGLER(RTLdrGetSystemSymbol) +# define RTLdrGetType RT_MANGLER(RTLdrGetType) # define RTLdrIsLoadable RT_MANGLER(RTLdrIsLoadable) # define RTLdrLinkAddressToRva RT_MANGLER(RTLdrLinkAddressToRva) # define RTLdrLinkAddressToSegOffset RT_MANGLER(RTLdrLinkAddressToSegOffset) # define RTLdrLoad RT_MANGLER(RTLdrLoad) # define RTLdrLoadAppPriv RT_MANGLER(RTLdrLoadAppPriv) # define RTLdrLoadEx RT_MANGLER(RTLdrLoadEx) +# define RTLdrLoadSystem RT_MANGLER(RTLdrLoadSystem) # define RTLdrOpen RT_MANGLER(RTLdrOpen) +# define RTLdrOpenInMemory RT_MANGLER(RTLdrOpenInMemory) # define RTLdrOpenkLdr RT_MANGLER(RTLdrOpenkLdr) # define RTLdrRelocate RT_MANGLER(RTLdrRelocate) # define RTLdrRvaToSegOffset RT_MANGLER(RTLdrRvaToSegOffset) @@ -651,7 +739,10 @@ # define RTLockValidatorRecSharedCheckOrder RT_MANGLER(RTLockValidatorRecSharedCheckOrder) # define RTLockValidatorRecSharedCheckOrderAndBlocking RT_MANGLER(RTLockValidatorRecSharedCheckOrderAndBlocking) # define RTLockValidatorRecSharedCheckSignaller RT_MANGLER(RTLockValidatorRecSharedCheckSignaller) +# define RTLockValidatorRecSharedCreate RT_MANGLER(RTLockValidatorRecSharedCreate) +# define RTLockValidatorRecSharedCreateV RT_MANGLER(RTLockValidatorRecSharedCreateV) # define RTLockValidatorRecSharedDelete RT_MANGLER(RTLockValidatorRecSharedDelete) +# define RTLockValidatorRecSharedDestroy RT_MANGLER(RTLockValidatorRecSharedDestroy) # define RTLockValidatorRecSharedInit RT_MANGLER(RTLockValidatorRecSharedInit) # define RTLockValidatorRecSharedInitV RT_MANGLER(RTLockValidatorRecSharedInitV) # define RTLockValidatorRecSharedIsOwner RT_MANGLER(RTLockValidatorRecSharedIsOwner) @@ -737,6 +828,7 @@ # define RTManifestSetAttr RT_MANGLER(RTManifestSetAttr) # define RTManifestUnsetAttr RT_MANGLER(RTManifestUnsetAttr) # define RTManifestVerify RT_MANGLER(RTManifestVerify) +# define RTManifestVerifyDigestType RT_MANGLER(RTManifestVerifyDigestType) # define RTManifestVerifyFiles RT_MANGLER(RTManifestVerifyFiles) # define RTManifestVerifyFilesBuf RT_MANGLER(RTManifestVerifyFilesBuf) # define RTManifestWriteFiles RT_MANGLER(RTManifestWriteFiles) @@ -749,7 +841,7 @@ # define RTMd5Init RT_MANGLER(RTMd5Init) # define RTMd5ToString RT_MANGLER(RTMd5ToString) # define RTMd5Update RT_MANGLER(RTMd5Update) -# define RTMemAllocExTag RT_MANGLER(RTMemAllocExTag) /* r0drv */ +# define RTMemAllocExTag RT_MANGLER(RTMemAllocExTag) # define RTMemAllocTag RT_MANGLER(RTMemAllocTag) # define RTMemAllocVarTag RT_MANGLER(RTMemAllocVarTag) # define RTMemAllocZTag RT_MANGLER(RTMemAllocZTag) @@ -789,7 +881,7 @@ # define RTMemExecAllocTag RT_MANGLER(RTMemExecAllocTag) # define RTMemExecFree RT_MANGLER(RTMemExecFree) # define RTMemFree RT_MANGLER(RTMemFree) -# define RTMemFreeEx RT_MANGLER(RTMemFreeEx) /* r0drv */ +# define RTMemFreeEx RT_MANGLER(RTMemFreeEx) # define RTMemPageAllocTag RT_MANGLER(RTMemPageAllocTag) # define RTMemPageAllocZTag RT_MANGLER(RTMemPageAllocZTag) # define RTMemPageFree RT_MANGLER(RTMemPageFree) @@ -834,10 +926,13 @@ # define RTMpGetMaxCpuId RT_MANGLER(RTMpGetMaxCpuId) # define RTMpGetMaxFrequency RT_MANGLER(RTMpGetMaxFrequency) # define RTMpGetOnlineCount RT_MANGLER(RTMpGetOnlineCount) +# define RTMpGetOnlineCoreCount RT_MANGLER(RTMpGetOnlineCoreCount) # define RTMpGetOnlineSet RT_MANGLER(RTMpGetOnlineSet) # define RTMpGetPresentCount RT_MANGLER(RTMpGetPresentCount) +# define RTMpGetPresentCoreCount RT_MANGLER(RTMpGetPresentCoreCount) # define RTMpGetPresentSet RT_MANGLER(RTMpGetPresentSet) # define RTMpGetSet RT_MANGLER(RTMpGetSet) +# define RTMpGetCoreCount RT_MANGLER(RTMpGetCoreCount) # define RTMpIsCpuOnline RT_MANGLER(RTMpIsCpuOnline) # define RTMpIsCpuPossible RT_MANGLER(RTMpIsCpuPossible) /* r0drv */ # define RTMpIsCpuPresent RT_MANGLER(RTMpIsCpuPresent) @@ -880,7 +975,9 @@ # define RTNetIPv6PseudoChecksumEx RT_MANGLER(RTNetIPv6PseudoChecksumEx) # define RTNetTCPChecksum RT_MANGLER(RTNetTCPChecksum) # define RTNetUDPChecksum RT_MANGLER(RTNetUDPChecksum) +# define RTNetStrToMacAddr RT_MANGLER(RTNetStrToMacAddr) # define RTNetIsIPv4AddrStr RT_MANGLER(RTNetIsIPv4AddrStr) +# define RTNetStrToIPv4Addr RT_MANGLER(RTNetStrToIPv4Addr) # define RTNetIsIPv6AddrStr RT_MANGLER(RTNetIsIPv6AddrStr) # define RTOnceSlow RT_MANGLER(RTOnceSlow) # define RTOnceReset RT_MANGLER(RTOnceReset) @@ -894,6 +991,7 @@ # define RTPathAppPrivateArch RT_MANGLER(RTPathAppPrivateArch) # define RTPathAppPrivateArchTop RT_MANGLER(RTPathAppPrivateArchTop) # define RTPathAppPrivateNoArch RT_MANGLER(RTPathAppPrivateNoArch) +# define RTPathCalcRelative RT_MANGLER(RTPathCalcRelative) # define RTPathChangeToDosSlashes RT_MANGLER(RTPathChangeToDosSlashes) # define RTPathChangeToUnixSlashes RT_MANGLER(RTPathChangeToUnixSlashes) # define RTPathCompare RT_MANGLER(RTPathCompare) @@ -904,19 +1002,24 @@ # define RTPathExistsEx RT_MANGLER(RTPathExistsEx) # define RTPathExt RT_MANGLER(RTPathExt) # define RTPathFilename RT_MANGLER(RTPathFilename) +# define RTPathFilenameEx RT_MANGLER(RTPathFilenameEx) # define RTPathGetCurrent RT_MANGLER(RTPathGetCurrent) # define RTPathGetMode RT_MANGLER(RTPathGetMode) # define RTPathHasExt RT_MANGLER(RTPathHasExt) # define RTPathHasPath RT_MANGLER(RTPathHasPath) +# define RTPathIsSame RT_MANGLER(RTPathIsSame) # define RTPathJoin RT_MANGLER(RTPathJoin) # define RTPathJoinA RT_MANGLER(RTPathJoinA) # define RTPathJoinEx RT_MANGLER(RTPathJoinEx) # define RTPathParse RT_MANGLER(RTPathParse) +# define RTPathParsedReassemble RT_MANGLER(RTPathParsedReassemble) +# define RTPathParseSimple RT_MANGLER(RTPathParseSimple) # define RTPathQueryInfo RT_MANGLER(RTPathQueryInfo) # define RTPathQueryInfoEx RT_MANGLER(RTPathQueryInfoEx) # define RTPathReal RT_MANGLER(RTPathReal) # define RTPathRealDup RT_MANGLER(RTPathRealDup) # define RTPathRename RT_MANGLER(RTPathRename) +# define RTPathRmCmd RT_MANGLER(RTPathRmCmd) # define RTPathSetCurrent RT_MANGLER(RTPathSetCurrent) # define RTPathSetMode RT_MANGLER(RTPathSetMode) /* not-win */ # define RTPathSetOwner RT_MANGLER(RTPathSetOwner) /* not-win */ @@ -924,6 +1027,10 @@ # define RTPathSetTimes RT_MANGLER(RTPathSetTimes) # define RTPathSetTimesEx RT_MANGLER(RTPathSetTimesEx) # define RTPathSharedLibs RT_MANGLER(RTPathSharedLibs) +# define RTPathSplit RT_MANGLER(RTPathSplit) +# define RTPathSplitATag RT_MANGLER(RTPathSplitATag) +# define RTPathSplitFree RT_MANGLER(RTPathSplitFree) +# define RTPathSplitReassemble RT_MANGLER(RTPathSplitReassemble) # define RTPathStartsWith RT_MANGLER(RTPathStartsWith) # define RTPathStartsWithRoot RT_MANGLER(RTPathStartsWithRoot) # define RTPathStripExt RT_MANGLER(RTPathStripExt) @@ -1018,6 +1125,7 @@ # define RTR3InitExe RT_MANGLER(RTR3InitExe) # define RTR3InitExeNoArguments RT_MANGLER(RTR3InitExeNoArguments) # define RTR3InitEx RT_MANGLER(RTR3InitEx) +# define RTR3InitIsUnobtrusive RT_MANGLER(RTR3InitIsUnobtrusive) # define rtR3MemAlloc RT_MANGLER(rtR3MemAlloc) # define rtR3MemFree RT_MANGLER(rtR3MemFree) # define rtR3MemRealloc RT_MANGLER(rtR3MemRealloc) @@ -1172,6 +1280,7 @@ # define RTSgBufCopyFromBuf RT_MANGLER(RTSgBufCopyFromBuf) # define RTSgBufCopyToBuf RT_MANGLER(RTSgBufCopyToBuf) # define RTSgBufInit RT_MANGLER(RTSgBufInit) +# define RTSgBufIsZero RT_MANGLER(RTSgBufIsZero) # define RTSgBufReset RT_MANGLER(RTSgBufReset) # define RTSgBufSegArrayCreate RT_MANGLER(RTSgBufSegArrayCreate) # define RTSgBufSet RT_MANGLER(RTSgBufSet) @@ -1190,6 +1299,8 @@ # define RTSha256Init RT_MANGLER(RTSha256Init) # define RTSha256ToString RT_MANGLER(RTSha256ToString) # define RTSha256Update RT_MANGLER(RTSha256Update) +# define RTSha256Digest RT_MANGLER(RTSha256Digest) +# define RTSha256DigestFromFile RT_MANGLER(RTSha256DigestFromFile) # define RTSha512 RT_MANGLER(RTSha512) # define RTSha512Final RT_MANGLER(RTSha512Final) # define RTSha512FromString RT_MANGLER(RTSha512FromString) @@ -1241,7 +1352,11 @@ # define RTStrCacheCreate RT_MANGLER(RTStrCacheCreate) # define RTStrCacheDestroy RT_MANGLER(RTStrCacheDestroy) # define RTStrCacheEnter RT_MANGLER(RTStrCacheEnter) +# define RTStrCacheEnterLower RT_MANGLER(RTStrCacheEnterLower) +# define RTStrCacheEnterLowerN RT_MANGLER(RTStrCacheEnterLowerN) # define RTStrCacheEnterN RT_MANGLER(RTStrCacheEnterN) +# define RTStrCacheGetStats RT_MANGLER(RTStrCacheGetStats) +# define RTStrCacheIsRealImpl RT_MANGLER(RTStrCacheIsRealImpl) # define RTStrCacheLength RT_MANGLER(RTStrCacheLength) # define RTStrCacheRelease RT_MANGLER(RTStrCacheRelease) # define RTStrCacheRetain RT_MANGLER(RTStrCacheRetain) @@ -1286,6 +1401,9 @@ # define RTStrHash1N RT_MANGLER(RTStrHash1N) # define RTStrICmp RT_MANGLER(RTStrICmp) # define RTStrIStr RT_MANGLER(RTStrIStr) +# define RTStrIsCaseFoldable RT_MANGLER(RTStrIsCaseFoldable) +# define RTStrIsLowerCased RT_MANGLER(RTStrIsLowerCased) +# define RTStrIsUpperCased RT_MANGLER(RTStrIsUpperCased) # define RTStrIsValidEncoding RT_MANGLER(RTStrIsValidEncoding) # define RTStrmClearError RT_MANGLER(RTStrmClearError) # define RTStrmClose RT_MANGLER(RTStrmClose) @@ -1407,9 +1525,11 @@ # define RTTarList RT_MANGLER(RTTarList) # define RTTarOpen RT_MANGLER(RTTarOpen) # define RTTarSeekNextFile RT_MANGLER(RTTarSeekNextFile) +# define RTTcpClientCancelConnect RT_MANGLER(RTTcpClientCancelConnect) # define RTTcpClientClose RT_MANGLER(RTTcpClientClose) # define RTTcpClientCloseEx RT_MANGLER(RTTcpClientCloseEx) # define RTTcpClientConnect RT_MANGLER(RTTcpClientConnect) +# define RTTcpClientConnectEx RT_MANGLER(RTTcpClientConnectEx) # define RTTcpFlush RT_MANGLER(RTTcpFlush) # define RTTcpGetLocalAddress RT_MANGLER(RTTcpGetLocalAddress) # define RTTcpGetPeerAddress RT_MANGLER(RTTcpGetPeerAddress) @@ -1438,7 +1558,9 @@ # define RTTermRegisterCallback RT_MANGLER(RTTermRegisterCallback) # define RTTermRunCallbacks RT_MANGLER(RTTermRunCallbacks) # define RTTestBanner RT_MANGLER(RTTestBanner) +# define RTTestChangeName RT_MANGLER(RTTestChangeName) # define RTTestCreate RT_MANGLER(RTTestCreate) +# define RTTestCreateEx RT_MANGLER(RTTestCreateEx) # define RTTestDestroy RT_MANGLER(RTTestDestroy) # define RTTestErrorCount RT_MANGLER(RTTestErrorCount) # define RTTestErrorInc RT_MANGLER(RTTestErrorInc) @@ -1459,6 +1581,7 @@ # define RTTestIFailureDetails RT_MANGLER(RTTestIFailureDetails) # define RTTestIFailureDetailsV RT_MANGLER(RTTestIFailureDetailsV) # define RTTestInitAndCreate RT_MANGLER(RTTestInitAndCreate) +# define RTTestInitExAndCreate RT_MANGLER(RTTestInitExAndCreate) # define RTTestIPassed RT_MANGLER(RTTestIPassed) # define RTTestIPassedV RT_MANGLER(RTTestIPassedV) # define RTTestIPrintf RT_MANGLER(RTTestIPrintf) @@ -1479,8 +1602,11 @@ # define RTTestSetDefault RT_MANGLER(RTTestSetDefault) # define RTTestSkipAndDestroy RT_MANGLER(RTTestSkipAndDestroy) # define RTTestSkipAndDestroyV RT_MANGLER(RTTestSkipAndDestroyV) +# define RTTestSkipped RT_MANGLER(RTTestSkipped) +# define RTTestSkippedV RT_MANGLER(RTTestSkippedV) # define RTTestSub RT_MANGLER(RTTestSub) # define RTTestSubDone RT_MANGLER(RTTestSubDone) +# define RTTestSubErrorCount RT_MANGLER(RTTestSubErrorCount) # define RTTestSubF RT_MANGLER(RTTestSubF) # define RTTestSubV RT_MANGLER(RTTestSubV) # define RTTestSummaryAndDestroy RT_MANGLER(RTTestSummaryAndDestroy) @@ -1492,6 +1618,12 @@ # define RTThreadCreate RT_MANGLER(RTThreadCreate) # define RTThreadCreateF RT_MANGLER(RTThreadCreateF) # define RTThreadCreateV RT_MANGLER(RTThreadCreateV) +# define RTThreadCtxHooksAreRegistered RT_MANGLER(RTThreadCtxHooksAreRegistered) /* r0drv */ +# define RTThreadCtxHooksCreate RT_MANGLER(RTThreadCtxHooksCreate) /* r0drv */ +# define RTThreadCtxHooksDeregister RT_MANGLER(RTThreadCtxHooksDeregister) /* r0drv */ +# define RTThreadCtxHooksRegister RT_MANGLER(RTThreadCtxHooksRegister) /* r0drv */ +# define RTThreadCtxHooksRelease RT_MANGLER(RTThreadCtxHooksRelease) /* r0drv */ +# define RTThreadCtxHooksRetain RT_MANGLER(RTThreadCtxHooksRetain) /* r0drv */ # define RTThreadFromNative RT_MANGLER(RTThreadFromNative) # define RTThreadGetAffinity RT_MANGLER(RTThreadGetAffinity) # define RTThreadGetExecutionTimeMilli RT_MANGLER(RTThreadGetExecutionTimeMilli) @@ -1572,9 +1704,11 @@ # define RTTimerStart RT_MANGLER(RTTimerStart) # define RTTimerStop RT_MANGLER(RTTimerStop) # define RTTimeSet RT_MANGLER(RTTimeSet) +# define RTTimeSpecFromString RT_MANGLER(RTTimeSpecFromString) # define RTTimeSpecToString RT_MANGLER(RTTimeSpecToString) # define RTTimeSystemMilliTS RT_MANGLER(RTTimeSystemMilliTS) # define RTTimeSystemNanoTS RT_MANGLER(RTTimeSystemNanoTS) +# define RTTimeFromString RT_MANGLER(RTTimeFromString) # define RTTimeToString RT_MANGLER(RTTimeToString) # define RTTlsAlloc RT_MANGLER(RTTlsAlloc) # define RTTlsAllocEx RT_MANGLER(RTTlsAllocEx) @@ -1666,6 +1800,7 @@ # define RTVfsFileFromRTFile RT_MANGLER(RTVfsFileFromRTFile) # define RTVfsFileGetSize RT_MANGLER(RTVfsFileGetSize) # define RTVfsFileOpen RT_MANGLER(RTVfsFileOpen) +# define RTVfsFileOpenNormal RT_MANGLER(RTVfsFileOpenNormal) # define RTVfsFilePoll RT_MANGLER(RTVfsFilePoll) # define RTVfsFileQueryInfo RT_MANGLER(RTVfsFileQueryInfo) # define RTVfsFileRead RT_MANGLER(RTVfsFileRead) @@ -1686,6 +1821,7 @@ # define RTVfsIoStrmFromRTFile RT_MANGLER(RTVfsIoStrmFromRTFile) # define RTVfsIoStrmFromStdHandle RT_MANGLER(RTVfsIoStrmFromStdHandle) # define RTVfsIoStrmIsAtEnd RT_MANGLER(RTVfsIoStrmIsAtEnd) +# define RTVfsIoStrmOpenNormal RT_MANGLER(RTVfsIoStrmOpenNormal) # define RTVfsIoStrmPoll RT_MANGLER(RTVfsIoStrmPoll) # define RTVfsIoStrmQueryInfo RT_MANGLER(RTVfsIoStrmQueryInfo) # define RTVfsIoStrmRead RT_MANGLER(RTVfsIoStrmRead) @@ -1754,10 +1890,11 @@ # define RTZipDecompCreate RT_MANGLER(RTZipDecompCreate) # define RTZipDecompDestroy RT_MANGLER(RTZipDecompDestroy) # define RTZipDecompress RT_MANGLER(RTZipDecompress) +# define RTZipGzipCompressIoStream RT_MANGLER(RTZipGzipCompressIoStream) # define RTZipGzipDecompressIoStream RT_MANGLER(RTZipGzipDecompressIoStream) # define RTZipTarCmd RT_MANGLER(RTZipTarCmd) # define RTZipTarFsStreamFromIoStream RT_MANGLER(RTZipTarFsStreamFromIoStream) - +# define RTZipXarFsStreamFromIoStream RT_MANGLER(RTZipXarFsStreamFromIoStream) /* * Stable variables (alphabetical order): */ diff --git a/include/iprt/manifest.h b/include/iprt/manifest.h index f7092b2a..d40f601e 100644 --- a/include/iprt/manifest.h +++ b/include/iprt/manifest.h @@ -3,7 +3,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; @@ -60,18 +60,22 @@ RT_C_DECLS_BEGIN /** @name Digest types. */ typedef enum RTDIGESTTYPE { - /** CRC32 checksum */ - RTDIGESTTYPE_CRC32 = 1, - /** CRC64 checksum */ + /** Invalid digest value. */ + RTDIGESTTYPE_INVALID = 0, + /** CRC32 checksum. */ + RTDIGESTTYPE_CRC32, + /** CRC64 checksum. */ RTDIGESTTYPE_CRC64, - /** MD5 checksum (unsafe!) */ + /** MD5 checksum (unsafe!). */ RTDIGESTTYPE_MD5, - /** SHA1 checksum (unsafe!) */ + /** SHA1 checksum (unsafe!). */ RTDIGESTTYPE_SHA1, - /** SHA256 checksum */ + /** SHA256 checksum. */ RTDIGESTTYPE_SHA256, - /** SHA512 checksum */ - RTDIGESTTYPE_SHA512 + /** SHA512 checksum. */ + RTDIGESTTYPE_SHA512, + /** Usual 32-bit type blowup. */ + RTDIGESTTYPE_32BIT_HACK = 0x7fffffff } RTDIGESTTYPE; /** @} */ @@ -445,6 +449,7 @@ typedef RTMANIFESTTEST* PRTMANIFESTTEST; * @param piFailed A index to paTests in the * VERR_MANIFEST_DIGEST_MISMATCH error case * (optional). + * @deprecated Use the RTMANIFEST based API instead. */ RTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed); @@ -462,6 +467,7 @@ RTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTe * (optional). * @param pfnProgressCallback optional callback for the progress indication * @param pvUser user defined pointer for the callback + * @deprecated Use the RTMANIFEST based API instead. */ RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTPROGRESS pfnProgressCallback, void *pvUser); @@ -479,11 +485,25 @@ RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * co * @param cFiles Number of entries in papszFiles. * @param pfnProgressCallback optional callback for the progress indication * @param pvUser user defined pointer for the callback + * @deprecated Use the RTMANIFEST based API instead. */ RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, RTDIGESTTYPE enmDigestType, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser); +/** + * Queries the first digest type found in the given manifest. + * + * @returns iprt status code. + * + * @param pvBuf Pointer to memory buffer of the manifest file. + * @param cbSize Size of the memory buffer. + * @param penmDigestType Where to return the first digest type found in + * the manifest. + * @deprecated Use the RTMANIFEST based API instead. + */ +RTR3DECL(int) RTManifestVerifyDigestType(void const *pvBuf, size_t cbSize, RTDIGESTTYPE *penmDigestType); + /** * Verify the given SHA1 digests against the entries in the manifest file in * memory. @@ -497,6 +517,7 @@ RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, RTDIGESTTYPE enm * @param piFailed A index to paTests in the * VERR_MANIFEST_DIGEST_MISMATCH error case * (optional). + * @deprecated Use the RTMANIFEST based API instead. */ RTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed); @@ -512,6 +533,7 @@ RTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTE * @param enmDigestType Which type of digest ("SHA1", "SHA256", ...) * @param paFiles Array of file names and digests. * @param cFiles Number of entries in paFiles. + * @deprecated Use the RTMANIFEST based API instead. */ RTR3DECL(int) RTManifestWriteFilesBuf(void **ppvBuf, size_t *pcbSize, RTDIGESTTYPE enmDigestType, PRTMANIFESTTEST paFiles, size_t cFiles); diff --git a/include/iprt/md5.h b/include/iprt/md5.h index e085abb6..f9f48320 100644 --- a/include/iprt/md5.h +++ b/include/iprt/md5.h @@ -3,7 +3,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/include/iprt/mem.h b/include/iprt/mem.h index 883de0fe..9b868065 100644 --- a/include/iprt/mem.h +++ b/include/iprt/mem.h @@ -3,7 +3,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; @@ -313,8 +313,16 @@ RTDECL(void) RTMemFree(void *pv) RT_NO_THROW; /** Allocate and free from any context. * Will return VERR_NOT_SUPPORTED if not supported. */ #define RTMEMALLOCEX_FLAGS_ANY_CTX (RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE) +/** Reachable by 16-bit address. + * Will return VERR_NOT_SUPPORTED if not supported. */ +#define RTMEMALLOCEX_FLAGS_16BIT_REACH RT_BIT(4) +/** Reachable by 32-bit address. + * Will return VERR_NOT_SUPPORTED if not supported. */ +#define RTMEMALLOCEX_FLAGS_32BIT_REACH RT_BIT(5) /** Mask of valid flags. */ -#define RTMEMALLOCEX_FLAGS_VALID_MASK UINT32_C(0x0000000f) +#define RTMEMALLOCEX_FLAGS_VALID_MASK UINT32_C(0x0000003f) +/** Mask of valid flags for ring-0. */ +#define RTMEMALLOCEX_FLAGS_VALID_MASK_R0 UINT32_C(0x0000000f) /** @} */ /** @@ -337,6 +345,9 @@ RTDECL(void) RTMemFree(void *pv) RT_NO_THROW; /** * Extended heap allocation API, custom tag. * + * Depending on the implementation, using this function may add extra overhead, + * so use the simpler APIs where ever possible. + * * @returns IPRT status code. * @retval VERR_NO_MEMORY if we're out of memory. * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory. @@ -357,6 +368,11 @@ RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, cons * * @param pv What to free, NULL is fine. * @param cb The amount of allocated memory. + * @param fFlags The flags specified when allocating the memory. + * Whether the exact flags are requires depends on + * the implementation, but in general, ring-0 + * doesn't require anything while ring-3 requires + * RTMEMALLOCEX_FLAGS_EXEC if used. */ RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW; diff --git a/include/iprt/memcache.h b/include/iprt/memcache.h index cad496b1..6cf8c2a5 100644 --- a/include/iprt/memcache.h +++ b/include/iprt/memcache.h @@ -37,7 +37,17 @@ RT_C_DECLS_BEGIN * @ingroup grp_rt * * Optimized allocation, initialization, freeing and destruction of memory - * objects of the same kind and size. + * objects of the same kind and size. Objects are constructed once, then + * allocated and freed one or more times, until finally destructed together with + * the cache (RTMemCacheDestroy). It's expected behavior, even when pfnCtor is + * NULL, that the user will be store information that should be persistent + * across RTMemCacheFree calls. + * + * The objects are zeroed prior to calling pfnCtor. For obvious reasons, the + * objects are not touched by the cache after that, so that RTMemCacheAlloc will + * return the object in the same state as when it as handed to RTMemCacheFree. + * + * @todo A callback for the reuse (at alloc time) might be of interest. * * @{ */ diff --git a/include/iprt/memobj.h b/include/iprt/memobj.h index 3a3b7025..b4498380 100644 --- a/include/iprt/memobj.h +++ b/include/iprt/memobj.h @@ -3,7 +3,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/include/iprt/mempool.h b/include/iprt/mempool.h index 6be563d3..22943342 100644 --- a/include/iprt/mempool.h +++ b/include/iprt/mempool.h @@ -3,7 +3,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/include/iprt/memtracker.h b/include/iprt/memtracker.h index 5d557b20..ca22fec5 100644 --- a/include/iprt/memtracker.h +++ b/include/iprt/memtracker.h @@ -3,7 +3,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/include/iprt/message.h b/include/iprt/message.h index b70a79be..1d78f176 100644 --- a/include/iprt/message.h +++ b/include/iprt/message.h @@ -3,7 +3,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; diff --git a/include/iprt/mp.h b/include/iprt/mp.h index 70c0bf5e..23ababc3 100644 --- a/include/iprt/mp.h +++ b/include/iprt/mp.h @@ -3,7 +3,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; @@ -116,6 +116,13 @@ RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet); */ RTDECL(RTCPUID) RTMpGetCount(void); +/** + * Get the count of physical CPU cores present in the system plus any that may + * possibly be hotplugged later. + * + * @returns The number of cores. + */ +RTDECL(RTCPUID) RTMpGetCoreCount(void); /** * Gets set of the CPUs present that are currently online. @@ -132,6 +139,14 @@ RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet); */ RTDECL(RTCPUID) RTMpGetOnlineCount(void); +/** + * Get the count of physical CPU cores in the system with one or more online + * threads. + * + * @returns The number of online cores. + */ +RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void); + /** * Checks if a CPU is online or not. * @@ -156,6 +171,13 @@ RTDECL(PRTCPUSET) RTMpGetPresentSet(PRTCPUSET pSet); */ RTDECL(RTCPUID) RTMpGetPresentCount(void); +/** + * Get the count of physical CPU cores present in the system. + * + * @returns The number of cores. + */ +RTDECL(RTCPUID) RTMpGetPresentCoreCount(void); + /** * Checks if a CPU is present in the system. * diff --git a/include/iprt/net.h b/include/iprt/net.h index 38e066b9..14c32f8b 100644 --- a/include/iprt/net.h +++ b/include/iprt/net.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2008-2012 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; @@ -38,6 +38,19 @@ RT_C_DECLS_BEGIN * @{ */ +/** + * Converts an stringified Ethernet MAC address into the RTMAC representation. + * + * @todo This should be move to some generic part of the runtime. + * + * @returns VINF_SUCCESS on success, VERR_GETOPT_INVALID_ARGUMENT_FORMAT on + * failure. + * + * @param pszValue The value to convert. + * @param pAddr Where to store the result. + */ +RTDECL(int) RTNetStrToMacAddr(const char *pszAddr, PRTMAC pMacAddr); + /** * IPv4 address. */ @@ -56,6 +69,17 @@ typedef RTNETADDRIPV4 const *PCRTNETADDRIPV4; */ RTDECL(bool) RTNetIsIPv4AddrStr(const char *pszAddress); +/** + * Converts an stringified IPv4 address into the RTNETADDRIPV4 representation. + * + * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on + * failure. + * + * @param pszAddr The value to convert. + * @param pAddr Where to store the result. + */ +RTDECL(int) RTNetStrToIPv4Addr(const char *pszAddr, PRTNETADDRIPV4 pAddr); + /** * IPv6 address. @@ -323,7 +347,8 @@ typedef RTNETIPV6 const *PCRTNETIPV6; /** The minimum IPv6 header length (in bytes). * Up to and including RTNETIPV6::ip6_dst. */ -#define RTNETIPV6_MIN_LEN (40) +#define RTNETIPV6_MIN_LEN (40) +#define RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN (32) RTDECL(uint32_t) RTNetIPv6PseudoChecksum(PCRTNETIPV6 pIpHdr); RTDECL(uint32_t) RTNetIPv6PseudoChecksumEx(PCRTNETIPV6 pIpHdr, uint8_t bProtocol, uint16_t cbPkt); @@ -737,6 +762,51 @@ typedef RTNETICMPV4 const *PCRTNETICMPV4; /** @todo add ICMPv6 when needed. */ +#define RTNETIPV6_PROT_ICMPV6 (58) +#define RTNETIPV6_ICMPV6_CODE_0 (0) +#define RTNETIPV6_ICMP_NS_TYPE (135) +#define RTNETIPV6_ICMP_NA_TYPE (136) +#define RTNETIPV6_ICMP_ND_SLLA_OPT (1) +#define RTNETIPV6_ICMP_ND_TLLA_OPT (2) +#define RTNETIPV6_ICMP_ND_LLA_LEN (1) + +/** ICMPv6 ND Source Link Layer Address option */ +#pragma pack(1) +typedef struct RTNETNDP_SLLA_OPT +{ + uint8_t type; + uint8_t len; + RTMAC slla; +} RTNETNDP_SLLA_OPT; +#pragma pack() + +AssertCompileSize(RTNETNDP_SLLA_OPT, 1+1+6); + +typedef RTNETNDP_SLLA_OPT *PRTNETNDP_SLLA_OPT; +typedef RTNETNDP_SLLA_OPT const *PCRTNETNDP_SLLA_OPT; + +/** ICMPv6 ND Neighbor Sollicitation */ +#pragma pack(1) +typedef struct RTNETNDP +{ + /** ICMPv6 type. */ + uint8_t icmp6_type; + /** ICMPv6 code. */ + uint8_t icmp6_code; + /** ICMPv6 checksum */ + uint16_t icmp6_cksum; + /** reserved */ + uint32_t reserved; + /** target address */ + RTNETADDRIPV6 target_address; +} RTNETNDP; +#pragma pack() +AssertCompileSize(RTNETNDP, 1+1+2+4+16); +/** Pointer to a NDP ND packet. */ +typedef RTNETNDP *PRTNETNDP; +/** Pointer to a const NDP NS packet. */ +typedef RTNETNDP const *PCRTNETNDP; + /** * Ethernet ARP header. @@ -805,9 +875,6 @@ typedef RTNETARPIPV4 *PRTNETARPIPV4; typedef RTNETARPIPV4 const *PCRTNETARPIPV4; -/** @todo RTNETNDP (IPv6)*/ - - /** @} */ RT_C_DECLS_END diff --git a/include/iprt/nocrt/amd64/fenv.h b/include/iprt/nocrt/amd64/fenv.h index 002aa01f..0daf3e21 100644 --- a/include/iprt/nocrt/amd64/fenv.h +++ b/include/iprt/nocrt/amd64/fenv.h @@ -3,7 +3,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/include/iprt/nocrt/amd64/math.h b/include/iprt/nocrt/amd64/math.h index 8d1e6536..762ac4f4 100644 --- a/include/iprt/nocrt/amd64/math.h +++ b/include/iprt/nocrt/amd64/math.h @@ -3,7 +3,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/include/iprt/nocrt/compiler/compiler.h b/include/iprt/nocrt/compiler/compiler.h index ea9f8952..77523d3c 100644 --- a/include/iprt/nocrt/compiler/compiler.h +++ b/include/iprt/nocrt/compiler/compiler.h @@ -3,7 +3,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/include/iprt/nocrt/compiler/gcc.h b/include/iprt/nocrt/compiler/gcc.h index 890448b3..9aeb3ce6 100644 --- a/include/iprt/nocrt/compiler/gcc.h +++ b/include/iprt/nocrt/compiler/gcc.h @@ -7,7 +7,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/include/iprt/nocrt/compiler/msc.h b/include/iprt/nocrt/compiler/msc.h index 1fbb3a14..6ee0003c 100644 --- a/include/iprt/nocrt/compiler/msc.h +++ b/include/iprt/nocrt/compiler/msc.h @@ -3,7 +3,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/include/iprt/nocrt/fenv.h b/include/iprt/nocrt/fenv.h index 32d8163c..710a6ee9 100644 --- a/include/iprt/nocrt/fenv.h +++ b/include/iprt/nocrt/fenv.h @@ -3,7 +3,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/include/iprt/nocrt/inttypes.h b/include/iprt/nocrt/inttypes.h index dc42dbb4..b86ec08d 100644 --- a/include/iprt/nocrt/inttypes.h +++ b/include/iprt/nocrt/inttypes.h @@ -3,7 +3,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/include/iprt/nocrt/limits.h b/include/iprt/nocrt/limits.h index 047f9644..2b377d16 100644 --- a/include/iprt/nocrt/limits.h +++ b/include/iprt/nocrt/limits.h @@ -3,7 +3,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/include/iprt/nocrt/math.h b/include/iprt/nocrt/math.h index da37c5f6..568f17c1 100644 --- a/include/iprt/nocrt/math.h +++ b/include/iprt/nocrt/math.h @@ -3,7 +3,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/include/iprt/nocrt/setjmp.h b/include/iprt/nocrt/setjmp.h index c7c7aaf0..9f61a955 100644 --- a/include/iprt/nocrt/setjmp.h +++ b/include/iprt/nocrt/setjmp.h @@ -3,7 +3,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/include/iprt/nocrt/stdarg.h b/include/iprt/nocrt/stdarg.h index daa6e0a7..3e52e0c1 100644 --- a/include/iprt/nocrt/stdarg.h +++ b/include/iprt/nocrt/stdarg.h @@ -3,7 +3,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/include/iprt/nocrt/stddef.h b/include/iprt/nocrt/stddef.h index 8487c26e..372f597d 100644 --- a/include/iprt/nocrt/stddef.h +++ b/include/iprt/nocrt/stddef.h @@ -3,7 +3,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/include/iprt/nocrt/stdlib.h b/include/iprt/nocrt/stdlib.h index 9bfc1d2f..7332ac26 100644 --- a/include/iprt/nocrt/stdlib.h +++ b/include/iprt/nocrt/stdlib.h @@ -3,7 +3,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/include/iprt/nocrt/string.h b/include/iprt/nocrt/string.h index 2ed2f72d..2ebee9b0 100644 --- a/include/iprt/nocrt/string.h +++ b/include/iprt/nocrt/string.h @@ -3,7 +3,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/include/iprt/nocrt/x86/fenv.h b/include/iprt/nocrt/x86/fenv.h index 3a3db7da..8dc2c90d 100644 --- a/include/iprt/nocrt/x86/fenv.h +++ b/include/iprt/nocrt/x86/fenv.h @@ -3,7 +3,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/include/iprt/nocrt/x86/math.h b/include/iprt/nocrt/x86/math.h index 1d5dbed4..6ed0337c 100644 --- a/include/iprt/nocrt/x86/math.h +++ b/include/iprt/nocrt/x86/math.h @@ -3,7 +3,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/include/iprt/once.h b/include/iprt/once.h index 31afb739..63ee6f79 100644 --- a/include/iprt/once.h +++ b/include/iprt/once.h @@ -3,7 +3,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; @@ -30,6 +30,7 @@ #include #include #include +#include RT_C_DECLS_BEGIN @@ -38,6 +39,28 @@ RT_C_DECLS_BEGIN * @{ */ +/** + * Callback that gets executed once. + * + * @returns IPRT style status code, RTOnce returns this. + * + * @param pvUser The user parameter. + */ +typedef DECLCALLBACK(int32_t) FNRTONCE(void *pvUser); +/** Pointer to a FNRTONCE. */ +typedef FNRTONCE *PFNRTONCE; + +/** + * Callback that gets executed on IPRT/process termination. + * + * @param pvUser The user parameter. + * @param fLazyCleanUpOk Indicates whether lazy clean-up is OK (see + * initterm.h). + */ +typedef DECLCALLBACK(void) FNRTONCECLEANUP(void *pvUser, bool fLazyCleanUpOk); +/** Pointer to a FNRTONCE. */ +typedef FNRTONCECLEANUP *PFNRTONCECLEANUP; + /** * Execute once structure. * @@ -47,13 +70,20 @@ RT_C_DECLS_BEGIN typedef struct RTONCE { /** Event semaphore that the other guys are blocking on. */ - RTSEMEVENTMULTI volatile hEventMulti; + RTSEMEVENTMULTI volatile hEventMulti; /** Reference counter for hEventMulti. */ - int32_t volatile cEventRefs; - /** -1 when uninitialized, 1 when initializing (busy) and 2 when done. */ - int32_t volatile iState; + int32_t volatile cEventRefs; + /** See RTONCESTATE. */ + int32_t volatile iState; /** The return code of pfnOnce. */ - int32_t volatile rc; + int32_t volatile rc; + + /** Pointer to the clean-up function. */ + PFNRTONCECLEANUP pfnCleanUp; + /** Argument to hand to the clean-up function. */ + void *pvUser; + /** Clean-up list entry. */ + RTLISTNODE CleanUpNode; } RTONCE; /** Pointer to a execute once struct. */ typedef RTONCE *PRTONCE; @@ -93,20 +123,24 @@ typedef enum RTONCESTATE } RTONCESTATE; /** Static initializer for RTONCE variables. */ -#define RTONCE_INITIALIZER { NIL_RTSEMEVENTMULTI, 0, RTONCESTATE_UNINITIALIZED, VERR_INTERNAL_ERROR } +#define RTONCE_INITIALIZER \ + { NIL_RTSEMEVENTMULTI, 0, RTONCESTATE_UNINITIALIZED, VERR_INTERNAL_ERROR, NULL, NULL, { NULL, NULL } } /** - * Callback that gets executed once. + * Serializes execution of the pfnOnce function, making sure it's + * executed exactly once and that nobody returns from RTOnce before + * it has executed successfully. * - * @returns IPRT style status code, RTOnce returns this. + * @returns IPRT like status code returned by pfnOnce. * - * @param pvUser1 The first user parameter. - * @param pvUser2 The second user parameter. + * @param pOnce Pointer to the execute once variable. + * @param pfnOnce The function to executed once. + * @param pfnCleanUp The function that will be doing the cleaning up. + * Optional. + * @param pvUser The user parameter for pfnOnce. */ -typedef DECLCALLBACK(int32_t) FNRTONCE(void *pvUser1, void *pvUser2); -/** Pointer to a FNRTONCE. */ -typedef FNRTONCE *PFNRTONCE; +RTDECL(int) RTOnceSlow(PRTONCE pOnce, PFNRTONCE pfnOnce, FNRTONCECLEANUP pfnCleanUp, void *pvUser); /** * Serializes execution of the pfnOnce function, making sure it's @@ -117,12 +151,21 @@ typedef FNRTONCE *PFNRTONCE; * * @param pOnce Pointer to the execute once variable. * @param pfnOnce The function to executed once. - * @param pvUser1 The first user parameter for pfnOnce. - * @param pvUser2 The second user parameter for pfnOnce. + * @param pvUser The user parameter for pfnOnce. */ -RTDECL(int) RTOnceSlow(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser2); +DECLINLINE(int) RTOnce(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser) +{ + int32_t iState = ASMAtomicUoReadS32(&pOnce->iState); + if (RT_LIKELY( iState == RTONCESTATE_DONE + || iState == RTONCESTATE_DONE_CREATING_SEM + || iState == RTONCESTATE_DONE_HAVE_SEM )) + return ASMAtomicUoReadS32(&pOnce->rc); + return RTOnceSlow(pOnce, pfnOnce, NULL, pvUser); +} /** + * Execute pfnOnce once and register a termination clean-up callback. + * * Serializes execution of the pfnOnce function, making sure it's * executed exactly once and that nobody returns from RTOnce before * it has executed successfully. @@ -131,19 +174,20 @@ RTDECL(int) RTOnceSlow(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pv * * @param pOnce Pointer to the execute once variable. * @param pfnOnce The function to executed once. - * @param pvUser1 The first user parameter for pfnOnce. - * @param pvUser2 The second user parameter for pfnOnce. + * @param pfnCleanUp The function that will be doing the cleaning up. + * @param pvUser The user parameter for pfnOnce. */ -DECLINLINE(int) RTOnce(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser2) +DECLINLINE(int) RTOnceEx(PRTONCE pOnce, PFNRTONCE pfnOnce, PFNRTONCECLEANUP pfnCleanUp, void *pvUser) { int32_t iState = ASMAtomicUoReadS32(&pOnce->iState); if (RT_LIKELY( iState == RTONCESTATE_DONE || iState == RTONCESTATE_DONE_CREATING_SEM || iState == RTONCESTATE_DONE_HAVE_SEM )) return ASMAtomicUoReadS32(&pOnce->rc); - return RTOnceSlow(pOnce, pfnOnce, pvUser1, pvUser2); + return RTOnceSlow(pOnce, pfnOnce, pfnCleanUp, pvUser); } + /** * Resets an execute once variable. * diff --git a/include/iprt/param.h b/include/iprt/param.h index 0e95e52d..5e80074a 100644 --- a/include/iprt/param.h +++ b/include/iprt/param.h @@ -3,7 +3,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/include/iprt/path.h b/include/iprt/path.h index 7e51f87d..7067a1b0 100644 --- a/include/iprt/path.h +++ b/include/iprt/path.h @@ -3,7 +3,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; @@ -49,16 +49,92 @@ RT_C_DECLS_BEGIN # define RTPATH_MAX (4096 + 4) /* (PATH_MAX + 1) on linux w/ some alignment */ #endif +/** @def RTPATH_TAG + * The default allocation tag used by the RTPath allocation APIs. + * + * When not defined before the inclusion of iprt/string.h, this will default to + * the pointer to the current file name. The string API will make of use of + * this as pointer to a volatile but read-only string. + */ +#ifndef RTPATH_TAG +# define RTPATH_TAG (__FILE__) +#endif + + +/** @name RTPATH_F_XXX - Generic flags for APIs working on the file system. + * @{ */ +/** Last component: Work on the link. */ +#define RTPATH_F_ON_LINK RT_BIT_32(0) +/** Last component: Follow if link. */ +#define RTPATH_F_FOLLOW_LINK RT_BIT_32(1) +/** Don't allow symbolic links as part of the path. + * @remarks this flag is currently not implemented and will be ignored. */ +#define RTPATH_F_NO_SYMLINKS RT_BIT_32(2) +/** @} */ + +/** Validates a flags parameter containing RTPATH_F_*. + * @remarks The parameters will be referenced multiple times. */ +#define RTPATH_F_IS_VALID(a_fFlags, a_fIgnore) \ + ( ((a_fFlags) & ~(uint32_t)((a_fIgnore) | RTPATH_F_NO_SYMLINKS)) == RTPATH_F_ON_LINK \ + || ((a_fFlags) & ~(uint32_t)((a_fIgnore) | RTPATH_F_NO_SYMLINKS)) == RTPATH_F_FOLLOW_LINK ) + + +/** @name RTPATH_STR_F_XXX - Generic flags for APIs working with path strings. + * @{ + */ +/** Host OS path style (default 0 value). */ +#define RTPATH_STR_F_STYLE_HOST UINT32_C(0x00000000) +/** DOS, OS/2 and Windows path style. */ +#define RTPATH_STR_F_STYLE_DOS UINT32_C(0x00000001) +/** Unix path style. */ +#define RTPATH_STR_F_STYLE_UNIX UINT32_C(0x00000002) +/** Reserved path style. */ +#define RTPATH_STR_F_STYLE_RESERVED UINT32_C(0x00000003) +/** The path style mask. */ +#define RTPATH_STR_F_STYLE_MASK UINT32_C(0x00000003) +/** Partial path - no start. + * This causes the API to skip the root specification parsing. */ +#define RTPATH_STR_F_NO_START UINT32_C(0x00000010) +/** Partial path - no end. + * This causes the API to skip the filename and dir-slash parsing. */ +#define RTPATH_STR_F_NO_END UINT32_C(0x00000020) +/** Partial path - no start and no end. */ +#define RTPATH_STR_F_MIDDLE (RTPATH_STR_F_NO_START | RTPATH_STR_F_NO_END) + +/** Reserved for future use. */ +#define RTPATH_STR_F_RESERVED_MASK UINT32_C(0x0000ffcc) +/** @} */ + +/** Validates a flags parameter containing RTPATH_FSTR_. + * @remarks The parameters will be references multiple times. */ +#define RTPATH_STR_F_IS_VALID(a_fFlags, a_fIgnore) \ + ( ((a_fFlags) & ~((uint32_t)(a_fIgnore) | RTPATH_STR_F_STYLE_MASK | RTPATH_STR_F_MIDDLE)) == 0 \ + && ((a_fFlags) & RTPATH_STR_F_STYLE_MASK) != RTPATH_STR_F_STYLE_RESERVED \ + && ((a_fFlags) & RTPATH_STR_F_RESERVED_MASK) == 0 ) + + +/** @def RTPATH_STYLE + * The host path style. This is set to RTPATH_STR_F_STYLE_DOS, + * RTPATH_STR_F_STYLE_UNIX, or other future styles. */ +#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) +# define RTPATH_STYLE RTPATH_STR_F_STYLE_DOS +#else +# define RTPATH_STYLE RTPATH_STR_F_STYLE_UNIX +#endif + + /** @def RTPATH_SLASH * The preferred slash character. * * @remark IPRT will always accept unix slashes. So, normally you would * never have to use this define. */ -#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) +#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS # define RTPATH_SLASH '\\' -#else +#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX # define RTPATH_SLASH '/' +#else +# error "Unsupported RTPATH_STYLE value." #endif /** @deprecated Use '/'! */ @@ -72,10 +148,12 @@ RT_C_DECLS_BEGIN * @remark IPRT will always accept unix slashes. So, normally you would * never have to use this define. */ -#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) +#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS # define RTPATH_SLASH_STR "\\" -#else +#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX # define RTPATH_SLASH_STR "/" +#else +# error "Unsupported RTPATH_STYLE value." #endif @@ -83,12 +161,14 @@ RT_C_DECLS_BEGIN * Checks if a character is a slash. * * @returns true if it's a slash and false if not. - * @returns @param ch Char to check. + * @returns @param a_ch Char to check. */ -#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) -# define RTPATH_IS_SLASH(ch) ( (ch) == '\\' || (ch) == '/' ) +#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS +# define RTPATH_IS_SLASH(a_ch) ( (a_ch) == '\\' || (a_ch) == '/' ) +#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX +# define RTPATH_IS_SLASH(a_ch) ( (a_ch) == '/' ) #else -# define RTPATH_IS_SLASH(ch) ( (ch) == '/' ) +# error "Unsupported RTPATH_STYLE value." #endif @@ -101,12 +181,14 @@ RT_C_DECLS_BEGIN * Use the RTPath@() instead. * * @returns true if it is and false if it isn't. - * @returns @param ch Char to check. + * @returns @param a_ch Char to check. */ -#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) -# define RTPATH_IS_VOLSEP(ch) ( (ch) == ':' ) +#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS +# define RTPATH_IS_VOLSEP(a_ch) ( (a_ch) == ':' ) +#elif RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX +# define RTPATH_IS_VOLSEP(a_ch) (false) #else -# define RTPATH_IS_VOLSEP(ch) (false) +# error "Unsupported RTPATH_STYLE value." #endif @@ -114,29 +196,10 @@ RT_C_DECLS_BEGIN * Checks if a character is path component separator * * @returns true if it is and false if it isn't. - * @returns @param ch Char to check. + * @returns @param a_ch Char to check. * @ */ -#define RTPATH_IS_SEP(ch) ( RTPATH_IS_SLASH(ch) || RTPATH_IS_VOLSEP(ch) ) - - -/** @name Generic RTPath flags - * @{ */ -/** Last component: Work on the link. */ -#define RTPATH_F_ON_LINK RT_BIT_32(0) -/** Last component: Follow if link. */ -#define RTPATH_F_FOLLOW_LINK RT_BIT_32(1) -/** Don't allow symbolic links as part of the path. - * @remarks this flag is currently not implemented and will be ignored. */ -#define RTPATH_F_NO_SYMLINKS RT_BIT_32(2) -/** @} */ - - -/** Validates a flags parameter containing RTPATH_F_*. - * @remarks The parameters will be referenced multiple times. */ -#define RTPATH_F_IS_VALID(fFlags, fIgnore) \ - ( ((fFlags) & ~(uint32_t)((fIgnore)|RTPATH_F_NO_SYMLINKS)) == RTPATH_F_ON_LINK \ - || ((fFlags) & ~(uint32_t)((fIgnore)|RTPATH_F_NO_SYMLINKS)) == RTPATH_F_FOLLOW_LINK ) +#define RTPATH_IS_SEP(a_ch) ( RTPATH_IS_SLASH(a_ch) || RTPATH_IS_VOLSEP(a_ch) ) /** @@ -293,7 +356,7 @@ RTDECL(char *) RTPathChangeToDosSlashes(char *pszPath, bool fForce); RTDECL(char *) RTPathChangeToUnixSlashes(char *pszPath, bool fForce); /** - * Parses a path. + * Simple parsing of the a path. * * It figures the length of the directory component, the offset of * the file name and the location of the suffix dot. @@ -310,7 +373,7 @@ RTDECL(char *) RTPathChangeToUnixSlashes(char *pszPath, bool fForce); * If empty string or if it's ending with a slash this * will be set to -1. Optional. */ -RTDECL(size_t) RTPathParse(const char *pszPath, size_t *pcchDir, ssize_t *poffName, ssize_t *poffSuff); +RTDECL(size_t) RTPathParseSimple(const char *pszPath, size_t *pcchDir, ssize_t *poffName, ssize_t *poffSuff); /** * Finds the filename in a path. @@ -321,6 +384,17 @@ RTDECL(size_t) RTPathParse(const char *pszPath, size_t *pcchDir, ssize_t *poffNa */ RTDECL(char *) RTPathFilename(const char *pszPath); +/** + * Finds the filename in a path, extended version. + * + * @returns Pointer to filename within pszPath. + * @returns NULL if no filename (i.e. empty string or ends with a slash). + * @param pszPath Path to find filename in. + * @param fFlags RTPATH_STR_F_STYLE_XXX. Other RTPATH_STR_F_XXX flags + * will be ignored. + */ +RTDECL(char *) RTPathFilenameEx(const char *pszPath, uint32_t fFlags); + /** * Finds the extension part of in a path. * @@ -388,6 +462,329 @@ RTDECL(size_t) RTPathCountComponents(const char *pszPath); */ RTDECL(int) RTPathCopyComponents(char *pszDst, size_t cbDst, const char *pszSrc, size_t cComponents); +/** @name Path properties returned by RTPathParse and RTPathSplit. + * @{ */ + +/** Indicates that there is a filename. + * If not set, either a lone root spec was given (RTPATH_PROP_UNC, + * RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME) or the final component had a + * trailing slash (RTPATH_PROP_DIR_SLASH). */ +#define RTPATH_PROP_FILENAME UINT16_C(0x0001) +/** Indicates that a directory was specified using a trailing slash. + * @note This is not set for lone root specifications (RTPATH_PROP_UNC, + * RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME). + * @note The slash is not counted into the last component. However, it is + * counted into cchPath. */ +#define RTPATH_PROP_DIR_SLASH UINT16_C(0x0002) + +/** The filename has a suffix (extension). */ +#define RTPATH_PROP_SUFFIX UINT16_C(0x0004) +/** Indicates that this is an UNC path (Windows and OS/2 only). + * + * UNC = Universal Naming Convention. It is on the form '//Computer/', + * '//Namespace/', '//ComputerName/Resource' and '//Namespace/Resource'. + * RTPathParse, RTPathSplit and friends does not consider the 'Resource' as + * part of the UNC root specifier. Thus the root specs for the above examples + * would be '//ComputerName/' or '//Namespace/'. + * + * Please note that '//something' is not a UNC path, there must be a slash + * following the computer or namespace. + */ +#define RTPATH_PROP_UNC UINT16_C(0x0010) +/** A root slash was specified (unix style root). + * (While the path must relative if not set, this being set doesn't make it + * absolute.) + * + * This will be set in the following examples: '/', '/bin', 'C:/', 'C:/Windows', + * '//./', '//./PhysicalDisk0', '//example.org/', and '//example.org/share'. + * + * It will not be set for the following examples: '.', 'bin/ls', 'C:', and + * 'C:Windows'. + */ +#define RTPATH_PROP_ROOT_SLASH UINT16_C(0x0020) +/** A volume is specified (Windows, DOS and OS/2). + * For examples: 'C:', 'C:/', and 'A:/AutoExec.bat'. */ +#define RTPATH_PROP_VOLUME UINT16_C(0x0040) +/** The path is absolute, i.e. has a root specifier (root-slash, + * volume or UNC) and contains no winding '..' bits, though it may contain + * unnecessary slashes (RTPATH_PROP_EXTRA_SLASHES) and '.' components + * (RTPATH_PROP_DOT_REFS). + * + * On systems without volumes and UNC (unix style) it will be set for '/', + * '/bin/ls', and '/bin//./ls', but not for 'bin/ls', /bin/../usr/bin/env', + * '/./bin/ls' or '/.'. + * + * On systems with volumes, it will be set for 'C:/', C:/Windows', and + * 'C:/./Windows//', but not for 'C:', 'C:Windows', or 'C:/Windows/../boot.ini'. + * + * On systems with UNC paths, it will be set for '//localhost/', + * '//localhost/C$', '//localhost/C$/Windows/System32', '//localhost/.', and + * '//localhost/C$//./AutoExec.bat', but not for + * '//localhost/C$/Windows/../AutoExec.bat'. + * + * @note For the RTPathAbs definition, this flag needs to be set while both + * RTPATH_PROP_EXTRA_SLASHES and RTPATH_PROP_DOT_REFS must be cleared. + */ +#define RTPATH_PROP_ABSOLUTE UINT16_C(0x0100) +/** Relative path. Inverse of RTPATH_PROP_ABSOLUTE. */ +#define RTPATH_PROP_RELATIVE UINT16_C(0x0200) +/** The path contains unnecessary slashes. Meaning, that if */ +#define RTPATH_PROP_EXTRA_SLASHES UINT16_C(0x0400) +/** The path contains references to the special '.' (dot) directory link. */ +#define RTPATH_PROP_DOT_REFS UINT16_C(0x0800) +/** The path contains references to the special '..' (dot) directory link. + * RTPATH_PROP_RELATIVE will always be set together with this. */ +#define RTPATH_PROP_DOTDOT_REFS UINT16_C(0x1000) + + +/** Macro to determin whether to insert a slash after the first component when + * joining it with something else. + * (All other components in a split or parsed path requies slashes added.) */ +#define RTPATH_PROP_FIRST_NEEDS_NO_SLASH(a_fProps) \ + RT_BOOL( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) ) + +/** Macro to determin whether there is a root specification of any kind + * (unix, volumes, unc). */ +#define RTPATH_PROP_HAS_ROOT_SPEC(a_fProps) \ + RT_BOOL( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) ) + +/** @} */ + + +/** + * Parsed path. + * + * The first component is the root, volume or UNC specifier, if present. Use + * RTPATH_PROP_HAS_ROOT_SPEC() on RTPATHPARSED::fProps to determine its + * precense. + * + * Other than the root component, no component will include directory separators + * (slashes). + */ +typedef struct RTPATHPARSED +{ + /** Number of path components. + * This will always be set on VERR_BUFFER_OVERFLOW returns from RTPathParsed + * so the caller can calculate the required buffer size. */ + uint16_t cComps; + /** Path property flags, RTPATH_PROP_XXX */ + uint16_t fProps; + /** On success this is the length of the described path, i.e. sum of all + * component lengths and necessary separators. + * Do NOT use this to index in the source path in case it contains + * unnecessary slashes that RTPathParsed has ignored here. */ + uint16_t cchPath; + /** Reserved for future use. */ + uint16_t u16Reserved; + /** The offset of the filename suffix, offset of the NUL char if none. */ + uint16_t offSuffix; + /** The lenght of the suffix. */ + uint16_t cchSuffix; + /** Array of component descriptors (variable size). + * @note Don't try figure the end of the input path by adding up off and cch + * of the last component. If RTPATH_PROP_DIR_SLASH is set, there may + * be one or more trailing slashes that are unaccounted for! */ + struct + { + /** The offset of the component. */ + uint16_t off; + /** The length of the component. */ + uint16_t cch; + } aComps[1]; +} RTPATHPARSED; +/** Pointer to to a parsed path result. */ +typedef RTPATHPARSED *PRTPATHPARSED; +/** Pointer to to a const parsed path result. */ +typedef RTPATHPARSED *PCRTPATHPARSED; + + +/** + * Parses the path. + * + * @returns IPRT status code. + * @retval VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer. + * @retval VERR_INVALID_PARAMETER if cbOutput is less than the RTPATHPARSED + * strucuture. No output. (asserted) + * @retval VERR_BUFFER_OVERFLOW there are more components in the path than + * there is space in aComps. The required amount of space can be + * determined from the pParsed->cComps: + * @code + * RT_OFFSETOF(RTPATHPARSED, aComps[pParsed->cComps]) + * @endcode + * @retval VERR_PATH_ZERO_LENGTH if the path is empty. + * + * @param pszPath The path to parse. + * @param pParsed Where to store the details of the parsed path. + * @param cbParsed The size of the buffer. Must be at least the + * size of RTPATHPARSED. + * @param fFlags Combination of RTPATH_STR_F_XXX flags. + * Most users will pass 0. + * @sa RTPathSplit, RTPathSplitA. + */ +RTDECL(int) RTPathParse(const char *pszPath, PRTPATHPARSED pParsed, size_t cbParsed, uint32_t fFlags); + +/** + * Reassembles a path parsed by RTPathParse. + * + * This will be more useful as more APIs manipulating the RTPATHPARSED output + * are added. + * + * @returns IPRT status code. + * @retval VERR_BUFFER_OVERFLOW if @a cbDstPath is less than or equal to + * RTPATHPARSED::cchPath. + * + * @param pszSrcPath The source path. + * @param pParsed The parser output for @a pszSrcPath. + * @param fFlags Combination of RTPATH_STR_F_STYLE_XXX. + * Most users will pass 0. + * @param pszDstPath Pointer to the buffer where the path is to be + * reassembled. + * @param cbDstPath The size of the output buffer. + */ +RTDECL(int) RTPathParsedReassemble(const char *pszSrcPath, PRTPATHPARSED pParsed, uint32_t fFlags, + char *pszDstPath, size_t cbDstPath); + + +/** + * Output buffer for RTPathSplit and RTPathSplitA. + */ +typedef struct RTPATHSPLIT +{ + /** Number of path components. + * This will always be set on VERR_BUFFER_OVERFLOW returns from RTPathParsed + * so the caller can calculate the required buffer size. */ + uint16_t cComps; + /** Path property flags, RTPATH_PROP_XXX */ + uint16_t fProps; + /** On success this is the length of the described path, i.e. sum of all + * component lengths and necessary separators. + * Do NOT use this to index in the source path in case it contains + * unnecessary slashes that RTPathSplit has ignored here. */ + uint16_t cchPath; + /** Reserved (internal use). */ + uint16_t u16Reserved; + /** The amount of memory used (on success) or required (on + * VERR_BUFFER_OVERFLOW) of this structure and it's strings. */ + uint32_t cbNeeded; + /** Pointer to the filename suffix (the dot), if any. Points to the NUL + * character of the last component if none or if RTPATH_PROP_DIR_SLASH is + * present. */ + const char *pszSuffix; + /** Array of component strings (variable size). */ + char *apszComps[1]; +} RTPATHSPLIT; +/** Pointer to a split path buffer. */ +typedef RTPATHSPLIT *PRTPATHSPLIT; +/** Pointer to a const split path buffer. */ +typedef RTPATHSPLIT const *PCRTPATHSPLIT; + +/** + * Splits the path into individual component strings, carved from user supplied + * the given buffer block. + * + * @returns IPRT status code. + * @retval VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer. + * @retval VERR_INVALID_PARAMETER if cbOutput is less than the RTPATHSPLIT + * strucuture. No output. (asserted) + * @retval VERR_BUFFER_OVERFLOW there are more components in the path than + * there is space in aComps. The required amount of space can be + * determined from the pParsed->cComps: + * @code + * RT_OFFSETOF(RTPATHPARSED, aComps[pParsed->cComps]) + * @endcode + * @retval VERR_PATH_ZERO_LENGTH if the path is empty. + * @retval VERR_FILENAME_TOO_LONG if the filename is too long (close to 64 KB). + * + * @param pszPath The path to parse. + * @param pSplit Where to store the details of the parsed path. + * @param cbSplit The size of the buffer pointed to by @a pSplit + * (variable sized array at the end). Must be at + * least the size of RTPATHSPLIT. + * @param fFlags Combination of RTPATH_STR_F_XXX flags. + * Most users will pass 0. + * + * @sa RTPathSplitA, RTPathParse. + */ +RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit, uint32_t fFlags); + +/** + * Splits the path into individual component strings, allocating the buffer on + * the default thread heap. + * + * @returns IPRT status code. + * @retval VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer. + * @retval VERR_PATH_ZERO_LENGTH if the path is empty. + * + * @param pszPath The path to parse. + * @param ppSplit Where to return the pointer to the output on + * success. This must be freed by calling + * RTPathSplitFree(). + * @param fFlags Combination of RTPATH_STR_F_XXX flags. + * Most users will pass 0. + * @sa RTPathSplitFree, RTPathSplit, RTPathParse. + */ +#define RTPathSplitA(pszPath, ppSplit, fFlags) RTPathSplitATag(pszPath, ppSplit, fFlags, RTPATH_TAG) + +/** + * Splits the path into individual component strings, allocating the buffer on + * the default thread heap. + * + * @returns IPRT status code. + * @retval VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer. + * @retval VERR_PATH_ZERO_LENGTH if the path is empty. + * + * @param pszPath The path to parse. + * @param ppSplit Where to return the pointer to the output on + * success. This must be freed by calling + * RTPathSplitFree(). + * @param fFlags Combination of RTPATH_STR_F_XXX flags. + * Most users will pass 0. + * @param pszTag Allocation tag used for statistics and such. + * @sa RTPathSplitFree, RTPathSplit, RTPathParse. + */ +RTDECL(int) RTPathSplitATag(const char *pszPath, PRTPATHSPLIT *ppSplit, uint32_t fFlags, const char *pszTag); + +/** + * Frees buffer returned by RTPathSplitA. + * + * @param pSplit What RTPathSplitA returned. + * @sa RTPathSplitA + */ +RTDECL(void) RTPathSplitFree(PRTPATHSPLIT pSplit); + +/** + * Reassembles a path parsed by RTPathSplit. + * + * This will be more useful as more APIs manipulating the RTPATHSPLIT output are + * added. + * + * @returns IPRT status code. + * @retval VERR_BUFFER_OVERFLOW if @a cbDstPath is less than or equal to + * RTPATHSPLIT::cchPath. + * + * @param pParsed The parser output for @a pszSrcPath. + * @param fFlags Combination of RTPATH_STR_F_STYLE_XXX. + * Most users will pass 0. + * @param pszDstPath Pointer to the buffer where the path is to be + * reassembled. + * @param cbDstPath The size of the output buffer. + */ +RTDECL(int) RTPathSplitReassemble(PRTPATHSPLIT pSplit, uint32_t fFlags, char *pszDstPath, size_t cbDstPath); + +/** + * Checks if the two paths leads to the file system object. + * + * If the objects exist, we'll query attributes for them. If that's not + * conclusive (some OSes) or one of them doesn't exist, we'll use a combination + * of RTPathAbs and RTPathCompare to determine the result. + * + * @returns true, false, or VERR_FILENAME_TOO_LONG. + * @param pszPath1 The first path. + * @param pszPath2 The seoncd path. + */ +RTDECL(int) RTPathIsSame(const char *pszPath1, const char *pszPath2); + + /** * Compares two paths. * @@ -593,6 +990,24 @@ typedef FNRTPATHTRAVERSER *PFNRTPATHTRAVERSER; RTDECL(int) RTPathTraverseList(const char *pszPathList, char chSep, PFNRTPATHTRAVERSER pfnCallback, void *pvUser1, void *pvUser2); +/** + * Calculate a relative path between the two given paths. + * + * @returns IPRT status code. + * @retval VINF_SUCCESS on success. + * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within + * cbPathDst bytes. + * @retval VERR_NOT_SUPPORTED if both paths start with different volume specifiers. + * @param pszPathDst Where to store the resulting path. + * @param cbPathDst The size of the buffer pszPathDst points to, + * terminator included. + * @param pszPathFrom The path to start from creating the relative path. + * @param pszPathTo The path to reach with the created relative path. + */ +RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst, + const char *pszPathFrom, + const char *pszPathTo); + #ifdef IN_RING3 /** @@ -616,7 +1031,7 @@ RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath); /** * Gets the user documents directory. * - * The returned path isn't guarantied to exist. + * The returned path isn't guaranteed to exist. * * @returns iprt status code. * @param pszPath Buffer where to store the path. @@ -932,6 +1347,17 @@ RTR3DECL(int) RTPathRename(const char *pszSrc, const char *pszDst, unsigned fRe */ RTR3DECL(int) RTPathUnlink(const char *pszPath, uint32_t fUnlink); +/** + * A /bin/rm tool. + * + * @returns Program exit code. + * + * @param cArgs The number of arguments. + * @param papszArgs The argument vector. (Note that this may be + * reordered, so the memory must be writable.) + */ +RTDECL(RTEXITCODE) RTPathRmCmd(unsigned cArgs, char **papszArgs); + #endif /* IN_RING3 */ /** @} */ diff --git a/include/iprt/pipe.h b/include/iprt/pipe.h index 11715c88..ec9f891d 100644 --- a/include/iprt/pipe.h +++ b/include/iprt/pipe.h @@ -3,7 +3,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/include/iprt/power.h b/include/iprt/power.h index 7a290734..49942736 100644 --- a/include/iprt/power.h +++ b/include/iprt/power.h @@ -3,7 +3,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/include/iprt/process.h b/include/iprt/process.h index b359e8ad..790470f4 100644 --- a/include/iprt/process.h +++ b/include/iprt/process.h @@ -3,7 +3,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/include/iprt/queueatomic.h b/include/iprt/queueatomic.h new file mode 100644 index 00000000..b5de9485 --- /dev/null +++ b/include/iprt/queueatomic.h @@ -0,0 +1,123 @@ +/** @file + * IPRT - Generic Work Queue with concurrent atomic access. + */ + +/* + * 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 ___iprt_queueatomic_h +#define ___iprt_queueatomic_h + +#include +#include + +/** @defgroup grp_rt_list RTQueueAtomic - Generic Work Queue + * @ingroup grp_rt + * + * Implementation of a lockless work queue for threaded environments. + * @{ + */ + +RT_C_DECLS_BEGIN + +/** + * A work item + */ +typedef struct RTQUEUEATOMICITEM +{ + /** Pointer to the next work item in the list. */ + struct RTQUEUEATOMICITEM * volatile pNext; +} RTQUEUEATOMICITEM; +/** Pointer to a work item. */ +typedef RTQUEUEATOMICITEM *PRTQUEUEATOMICITEM; +/** Pointer to a work item pointer. */ +typedef PRTQUEUEATOMICITEM *PPRTQUEUEATOMICITEM; + +/** + * Work queue. + */ +typedef struct RTQUEUEATOMIC +{ + /* Head of the work queue. */ + volatile PRTQUEUEATOMICITEM pHead; +} RTQUEUEATOMIC; +/** Pointer to a work queue. */ +typedef RTQUEUEATOMIC *PRTQUEUEATOMIC; + +/** + * Initialize a work queue. + * + * @param pWorkQueue Pointer to an unitialised work queue. + */ +DECLINLINE(void) RTQueueAtomicInit(PRTQUEUEATOMIC pWorkQueue) +{ + ASMAtomicWriteNullPtr(&pWorkQueue->pHead); +} + +/** + * Insert a new item into the work queue. + * + * @param pWorkQueue The work queue to insert into. + * @param pItem The item to insert. + */ +DECLINLINE(void) RTQueueAtomicInsert(PRTQUEUEATOMIC pWorkQueue, PRTQUEUEATOMICITEM pItem) +{ + PRTQUEUEATOMICITEM pNext = ASMAtomicUoReadPtrT(&pWorkQueue->pHead, PRTQUEUEATOMICITEM); + PRTQUEUEATOMICITEM pHeadOld; + pItem->pNext = pNext; + while (!ASMAtomicCmpXchgExPtr(&pWorkQueue->pHead, pItem, pNext, &pHeadOld)) + { + pNext = pHeadOld; + Assert(pNext != pItem); + pItem->pNext = pNext; + ASMNopPause(); + } +} + +/** + * Remove all items from the given work queue and return them in the inserted order. + * + * @returns Pointer to the first item. + * @param pWorkQueue The work queue. + */ +DECLINLINE(PRTQUEUEATOMICITEM) RTQueueAtomicRemoveAll(PRTQUEUEATOMIC pWorkQueue) +{ + PRTQUEUEATOMICITEM pHead = ASMAtomicXchgPtrT(&pWorkQueue->pHead, NULL, PRTQUEUEATOMICITEM); + + /* Reverse it. */ + PRTQUEUEATOMICITEM pCur = pHead; + pHead = NULL; + while (pCur) + { + PRTQUEUEATOMICITEM pInsert = pCur; + pCur = pCur->pNext; + pInsert->pNext = pHead; + pHead = pInsert; + } + + return pHead; +} + +RT_C_DECLS_END + +/** @} */ + +#endif diff --git a/include/iprt/rand.h b/include/iprt/rand.h index f9fa5b80..3a58c5dd 100644 --- a/include/iprt/rand.h +++ b/include/iprt/rand.h @@ -3,7 +3,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/include/iprt/runtime-loader.h b/include/iprt/runtime-loader.h index 81ba40e6..58d6bc60 100644 --- a/include/iprt/runtime-loader.h +++ b/include/iprt/runtime-loader.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2008-2010 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; @@ -115,7 +115,7 @@ static RTLDRSHAREDFUNC g_aSharedFuncs[] = * The function which does the actual work for RT_RUNTIME_LOADER_FUNCTION, * serialised for thread safety. */ -static DECLCALLBACK(int) rtldrLoadOnce(void *, void *) +static DECLCALLBACK(int) rtldrLoadOnce(void *) { RTLDRMOD hLib; int rc; @@ -144,7 +144,7 @@ RTR3DECL(int) RT_RUNTIME_LOADER_FUNCTION(void) int rc; LogFlowFunc(("\n")); - rc = RTOnce(&s_Once, rtldrLoadOnce, NULL, NULL); + rc = RTOnce(&s_Once, rtldrLoadOnce, NULL); LogFlowFunc(("rc = %Rrc\n", rc)); return rc; diff --git a/include/iprt/runtime.h b/include/iprt/runtime.h index b70bfd1b..eb1a4ae9 100644 --- a/include/iprt/runtime.h +++ b/include/iprt/runtime.h @@ -3,7 +3,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/include/iprt/s3.h b/include/iprt/s3.h index 2c200d5a..3d448b01 100644 --- a/include/iprt/s3.h +++ b/include/iprt/s3.h @@ -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/include/iprt/semaphore.h b/include/iprt/semaphore.h index 0eba39c7..23e59dbb 100644 --- a/include/iprt/semaphore.h +++ b/include/iprt/semaphore.h @@ -3,7 +3,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/include/iprt/sg.h b/include/iprt/sg.h index d515de8b..d7083bbd 100644 --- a/include/iprt/sg.h +++ b/include/iprt/sg.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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; @@ -187,12 +187,12 @@ RTDECL(size_t) RTSgBufCopyToBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy); * * @returns Number of bytes copied. * @param pSgBuf The S/G buffer to copy to. - * @param pvBuf Buffer to copy the data into. + * @param pvBuf Buffer to copy the data from. * @param cbCopy How many bytes to copy. * * @note This operation advances the internal buffer pointer of the S/G buffer. */ -RTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy); +RTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, const void *pvBuf, size_t cbCopy); /** * Advances the internal buffer pointer. @@ -220,6 +220,17 @@ RTDECL(size_t) RTSgBufAdvance(PRTSGBUF pSgBuf, size_t cbAdvance); */ RTDECL(size_t) RTSgBufSegArrayCreate(PRTSGBUF pSgBuf, PRTSGSEG paSeg, unsigned *pcSeg, size_t cbData); +/** + * Returns whether the given S/G buffer is zeroed out from the current position + * upto the number of bytes to check. + * + * @returns true if the buffer has only zeros + * false otherwise. + * @param pSgBuf The S/G buffer. + * @param cbCheck Number of bytes to check. + */ +RTDECL(bool) RTSgBufIsZero(PRTSGBUF pSgBuf, size_t cbCheck); + /** * Maps the given S/G buffer to a segment array of another type (for example to * iovec on POSIX or WSABUF on Windows). diff --git a/include/iprt/sha.h b/include/iprt/sha.h index 046ca813..ea89759b 100644 --- a/include/iprt/sha.h +++ b/include/iprt/sha.h @@ -3,7 +3,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; @@ -215,7 +215,32 @@ RTDECL(int) RTSha256ToString(uint8_t const pabDigest[RTSHA256_HASH_SIZE], char * */ RTDECL(int) RTSha256FromString(char const *pszDigest, uint8_t pabDigest[RTSHA256_HASH_SIZE]); +/** + * Creates a SHA256 digest for the given memory buffer. + * + * @returns iprt status code. + * + * @param pvBuf Memory buffer to create a + * SHA256 digest for. + * @param cbBuf The amount of data (in bytes). + * @param ppszDigest On success the SHA256 digest. + * @param pfnProgressCallback optional callback for the progress indication + * @param pvUser user defined pointer for the callback + */ +RTR3DECL(int) RTSha256Digest(void* pvBuf, size_t cbBuf, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser); +/** + * Creates a SHA256 digest for the given file. + * + * @returns iprt status code. + * + * @param pszFile Filename to create a SHA256 + * digest for. + * @param ppszDigest On success the SHA256 digest. + * @param pfnProgressCallback optional callback for the progress indication + * @param pvUser user defined pointer for the callback + */ +RTR3DECL(int) RTSha256DigestFromFile(const char *pszFile, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser); /** The size of a SHA-512 hash. */ #define RTSHA512_HASH_SIZE 64 diff --git a/include/iprt/sort.h b/include/iprt/sort.h index dd4e93e5..b9f9e1fb 100644 --- a/include/iprt/sort.h +++ b/include/iprt/sort.h @@ -3,7 +3,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/include/iprt/spinlock.h b/include/iprt/spinlock.h index 2c36a0fd..1ca3dfc0 100644 --- a/include/iprt/spinlock.h +++ b/include/iprt/spinlock.h @@ -3,7 +3,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; @@ -73,7 +73,6 @@ RTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock); * Acquires the spinlock. * * @param Spinlock The spinlock to acquire. - * @param pTmp Where to save the state. */ RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock); @@ -81,7 +80,6 @@ RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock); * Releases the spinlock. * * @param Spinlock The spinlock to acquire. - * @param pTmp The state to restore. (This better be the same as for the RTSpinlockAcquire() call!) */ RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock); diff --git a/include/iprt/stdint.h b/include/iprt/stdint.h index 59c2d726..ae94d668 100644 --- a/include/iprt/stdint.h +++ b/include/iprt/stdint.h @@ -3,7 +3,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; @@ -87,12 +87,12 @@ # undef IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES # ifdef __IBMCPP__ # if __IBMCPP__ < 350 && (defined(__WINDOWS__) || defined(_AIX) || defined(__OS2__)) -# defined IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES +# define IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES # endif # endif # ifdef __IBMC__ # if __IBMC__ < 350 && (defined(__WINDOWS__) || defined(_AIX) || defined(__OS2__)) -# defined IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES +# define IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES # endif # endif diff --git a/include/iprt/strcache.h b/include/iprt/strcache.h index d3883483..65cfd484 100644 --- a/include/iprt/strcache.h +++ b/include/iprt/strcache.h @@ -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; @@ -86,6 +86,35 @@ RTDECL(const char *) RTStrCacheEnterN(RTSTRCACHE hStrCache, const char *pchStrin RTDECL(const char *) RTStrCacheEnter(RTSTRCACHE hStrCache, const char *psz); +/** + * Enters a string into the cache in lower cased form. + * + * @returns Pointer to a read-only lower cased copy of the string. + * + * @param hStrCache Handle to the string cache. + * @param pchString Pointer to a string. This does not need to be + * zero terminated, but must not contain any zero + * characters. + * @param cchString The number of characters (bytes) to enter. + * + * @remarks It is implementation dependent whether the returned string pointer + * differs when entering the same string twice. + */ +RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString); + +/** + * Enters a string into the cache in lower cased form. + * + * @returns Pointer to a read-only lower cased copy of the string. + * + * @param hStrCache Handle to the string cache. + * @param psz Pointer to a zero terminated string. + * + * @remarks See RTStrCacheEnterN. + */ +RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz); + + /** * Retains a reference to a string. * @@ -100,8 +129,7 @@ RTDECL(uint32_t) RTStrCacheRetain(const char *psz); * @returns The new reference count. * UINT32_MAX is returned if the string pointer is invalid. * - * @param hStrCache Handle to the string cache. Passing NIL is ok, - * but this may come a performance hit. + * @param hStrCache Handle to the string cache. NIL is NOT allowed. * @param psz Pointer to a cached string. */ RTDECL(uint32_t) RTStrCacheRelease(RTSTRCACHE hStrCache, const char *psz); @@ -115,6 +143,45 @@ RTDECL(uint32_t) RTStrCacheRelease(RTSTRCACHE hStrCache, const char *psz); */ RTDECL(size_t) RTStrCacheLength(const char *psz); + +/** + * Gets cache statistics. + * + * All parameters, except @a hStrCache, are optional and can be NULL. + * + * @returns Number of strings, UINT32_MAX on failure (or not supported). + * @param hStrCache Handle to the string cache. + * @param pcbStrings The number of string bytes (including + * terminators) . + * @param pcbChunks Amount of memory we've allocated for the + * internal allocator. + * @param pcbBigEntries Amount of memory we've allocated off the heap + * for really long strings that doesn't fit in the + * internal allocator. + * @param pcHashCollisions Number of hash table insert collisions. + * @param pcHashCollisions2 Number of hash table secondary insert + * collisions. + * @param pcHashInserts Number of hash table inserts. + * @param pcRehashes The number of rehashes. + * + * @remarks This is not a stable interface as it needs to reflect the cache + * implementation. + */ +RTDECL(uint32_t) RTStrCacheGetStats(RTSTRCACHE hStrCache, size_t *pcbStrings, size_t *pcbChunks, size_t *pcbBigEntries, + uint32_t *pcHashCollisions, uint32_t *pcHashCollisions2, uint32_t *pcHashInserts, + uint32_t *pcRehashes); + +/** + * Indicates whether this a real string cache or a cheap place holder. + * + * A real string cache will return the same address when a string is added + * multiple times. + * + * @returns true / false. + */ +RTDECL(bool) RTStrCacheIsRealImpl(void); + + RT_C_DECLS_END #endif diff --git a/include/iprt/stream.h b/include/iprt/stream.h index e8ac0d08..720d6d84 100644 --- a/include/iprt/stream.h +++ b/include/iprt/stream.h @@ -3,7 +3,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/include/iprt/string.h b/include/iprt/string.h index 1f52c75d..fdc44fa6 100644 --- a/include/iprt/string.h +++ b/include/iprt/string.h @@ -166,7 +166,7 @@ RT_C_DECLS_BEGIN #define RTSTR_MAX (~(size_t)0) -/** @def RTMEM_TAG +/** @def RTSTR_TAG * The default allocation tag used by the RTStr allocation APIs. * * When not defined before the inclusion of iprt/string.h, this will default to @@ -2411,6 +2411,31 @@ RTDECL(char *) RTStrToLower(char *psz); */ RTDECL(char *) RTStrToUpper(char *psz); +/** + * Checks if the string is case foldable, i.e. whether it would change if + * subject to RTStrToLower or RTStrToUpper. + * + * @returns true / false + * @param psz The string in question. + */ +RTDECL(bool) RTStrIsCaseFoldable(const char *psz); + +/** + * Checks if the string is upper cased (no lower case chars in it). + * + * @returns true / false + * @param psz The string in question. + */ +RTDECL(bool) RTStrIsUpperCased(const char *psz); + +/** + * Checks if the string is lower cased (no upper case chars in it). + * + * @returns true / false + * @param psz The string in question. + */ +RTDECL(bool) RTStrIsLowerCased(const char *psz); + /** * Find the length of a zero-terminated byte string, given * a max string length. diff --git a/include/iprt/symlink.h b/include/iprt/symlink.h index 85edf1ad..2d1e618f 100644 --- a/include/iprt/symlink.h +++ b/include/iprt/symlink.h @@ -3,7 +3,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/include/iprt/system.h b/include/iprt/system.h index e7083e27..a86c937a 100644 --- a/include/iprt/system.h +++ b/include/iprt/system.h @@ -3,7 +3,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; @@ -199,7 +199,7 @@ RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t c /** Reboot the system after shutdown. */ #define RTSYSTEM_SHUTDOWN_REBOOT UINT32_C(0) /** Reboot the system after shutdown. - * The call may return VINF_SYS_MAY_POWER_OFF if the OS / + * The call may return VINF_SYS_MAY_POWER_OFF if the OS / * hardware combination may power off instead of halting. */ #define RTSYSTEM_SHUTDOWN_HALT UINT32_C(1) /** Power off the system after shutdown. @@ -229,10 +229,10 @@ RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t c * @returns IPRT status code on failure, on success it may or may not return * depending on the OS. * @retval VINF_SUCCESS - * @retval VINF_SYS_MAY_POWER_OFF - * @retval VERR_SYS_SHUTDOWN_FAILED - * @retval VERR_SYS_CANNOT_POWER_OFF - * + * @retval VINF_SYS_MAY_POWER_OFF + * @retval VERR_SYS_SHUTDOWN_FAILED + * @retval VERR_SYS_CANNOT_POWER_OFF + * * @param cMsDelay The delay before the actual reboot. If this is * not supported by the OS, an immediate reboot * will be performed. diff --git a/include/iprt/table.h b/include/iprt/table.h index 70023979..6746b963 100644 --- a/include/iprt/table.h +++ b/include/iprt/table.h @@ -3,7 +3,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/include/iprt/tar.h b/include/iprt/tar.h index 96fad7a6..0b85af37 100644 --- a/include/iprt/tar.h +++ b/include/iprt/tar.h @@ -51,6 +51,10 @@ typedef RTTARFILE *PRTTARFILE; /** Nil RTTARFILE interface handle. */ #define NIL_RTTARFILE ((RTTARFILE)0) +/** Maximum length of a tar filename, excluding the terminating '\0'. More + * does not fit into a tar record. */ +#define RTTAR_NAME_MAX 99 + /** * Opens a Tar archive. * diff --git a/include/iprt/tcp.h b/include/iprt/tcp.h index 32d7de45..0e6a4e94 100644 --- a/include/iprt/tcp.h +++ b/include/iprt/tcp.h @@ -170,6 +170,40 @@ RTR3DECL(int) RTTcpServerShutdown(PRTTCPSERVER pServer); */ RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock); +/** Opaque pointer used by RTTcpClientConnectEx and RTTcpClientCancelConnect. */ +typedef struct RTTCPCLIENTCONNECTCANCEL *PRTTCPCLIENTCONNECTCANCEL; + +/** + * Connect (as a client) to a TCP Server, extended version. + * + * @returns iprt status code. + * @param pszAddress The address to connect to. + * @param uPort The port to connect to. + * @param pSock Where to store the handle to the established connection. + * @param ppCancelCookie Where to store information for canceling the + * operation (from a different thread). Optional. + * + * The pointer _must_ be initialized to NULL before a + * series of connection attempts begins, i.e. at a time + * where there will be no RTTcpClientCancelConnect + * calls racing access. RTTcpClientCancelConnect will + * set it to a special non-NULL value that causes the + * current or/and next connect call to fail. + * + * @sa RTTcpClientCancelConnect + */ +RTR3DECL(int) RTTcpClientConnectEx(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock, + PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie); + +/** + * Cancels a RTTcpClientConnectEx call on a different thread. + * + * @returns iprt status code. + * @param ppCancelCookie The address of the cookie pointer shared with the + * connect call. + */ +RTR3DECL(int) RTTcpClientCancelConnect(PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie); + /** * Close a socket returned by RTTcpClientConnect(). * diff --git a/include/iprt/test.h b/include/iprt/test.h index c004ab4f..1788531e 100644 --- a/include/iprt/test.h +++ b/include/iprt/test.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-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; @@ -29,6 +29,7 @@ #include #include #include +#include RT_C_DECLS_BEGIN @@ -38,7 +39,7 @@ RT_C_DECLS_BEGIN */ /** A test handle. */ -typedef struct RTTESTINT *RTTEST; +typedef R3PTRTYPE(struct RTTESTINT *) RTTEST; /** A pointer to a test handle. */ typedef RTTEST *PRTTEST; /** A const pointer to a test handle. */ @@ -78,6 +79,65 @@ typedef enum RTTESTLVL */ RTR3DECL(int) RTTestCreate(const char *pszTest, PRTTEST phTest); +/** @name RTTEST_C_XXX - Flags for RTTestCreateEx. + * @{ */ +/** Whether to check the IPRT_TEST_XXX variables when constructing the + * instance. The following environment variables get checks: + * + * - IPRT_TEST_MAX_LEVEL: String value indicating which level. + * The env. var. is applied if the program specified the default level + * (by passing RTTESTLVL_INVALID). + * + * - IPRT_TEST_PIPE: The native pipe/fifo handle to write XML + * results to. + * The env. var. is applied if iNativeTestPipe is -1. + * + * - IPRT_TEST_FILE: Path to file/named-pipe/fifo/whatever to + * write XML results to. + * The env. var. is applied if the program specified a NULL path, it is + * not applied if the program hands us an empty string. + * + * - IPRT_TEST_OMIT_TOP_TEST: If present, this makes the XML output omit + * the top level test element. + * The env. var is applied when present. + * + */ +#define RTTEST_C_USE_ENV RT_BIT(0) +/** Whether to omit the top test in the XML. */ +#define RTTEST_C_XML_OMIT_TOP_TEST RT_BIT(1) +/** Whether to delay the top test XML element until testing commences. */ +#define RTTEST_C_XML_DELAY_TOP_TEST RT_BIT(2) +/** Whether to try install the test instance in the test TLS slot. Setting + * this flag is incompatible with using the RTTestIXxxx variant of the API. */ +#define RTTEST_C_NO_TLS RT_BIT(3) +/** Mask containing the valid bits. */ +#define RTTEST_C_VALID_MASK UINT32_C(0x0000000f) +/** @} */ + + +/** + * Creates a test instance. + * + * @returns IPRT status code. + * @param pszTest The test name. + * @param pszXmlFile The XML output file/pipe/whatever. + * @param fFlags Flags, see RTTEST_C_XXX. + * @param enmMaxLevel The max message level. Use RTTESTLVL_INVALID for + * the default output level or one from the + * environment. If specified, the environment variable + * will not be able to override it. + * @param iNativeTestPipe Native handle to a test pipe. -1 if not interested. + * @param pszXmlFile The XML output file name. If NULL the environment + * may be used. To selectively avoid that, pass an + * empty string. + * @param phTest Where to store the test instance handle. + * + * @note At the moment, we don't fail if @a pszXmlFile or @a iNativeTestPipe + * fails to open. This may change later. + */ +RTR3DECL(int) RTTestCreateEx(const char *pszTest, uint32_t fFlags, RTTESTLVL enmMaxLevel, + RTHCINTPTR iNativeTestPipe, const char *pszXmlFile, PRTTEST phTest); + /** * Initializes IPRT and creates a test instance. * @@ -101,6 +161,21 @@ RTR3DECL(int) RTTestCreate(const char *pszTest, PRTTEST phTest); */ RTR3DECL(RTEXITCODE) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest); +/** + * Variant of RTTestInitAndCreate that includes IPRT init flags and argument + * vectors. + * + * @returns RTEXITCODE_SUCCESS on success. On failure an error message is + * printed and a suitable exit code is return. + * + * @param cArgs Pointer to the argument count. + * @param ppapszArgs Pointer to the argument vector pointer. + * @param fRtInit Flags, see RTR3INIT_XXX. + * @param pszTest The test name. + * @param phTest Where to store the test instance handle. + */ +RTR3DECL(RTEXITCODE) RTTestInitExAndCreate(int cArgs, char ***papszArgs, uint32_t fRtInit, const char *pszTest, PRTTEST phTest); + /** * Destroys a test instance previously created by RTTestCreate. * @@ -119,6 +194,18 @@ RTR3DECL(int) RTTestDestroy(RTTEST hTest); */ RTR3DECL(int) RTTestSetDefault(RTTEST hNewDefaultTest, PRTTEST phOldTest); +/** + * Changes the test case name. + * + * @returns IRPT status code. + * @param hTest The test handle. If NIL_RTTEST we'll use the one + * associated with the calling thread. + * @param pszName The new test case name. Empty string is not accepted, + * nor are strings longer than 127 chars. Keep it short + * but descriptive. + */ +RTR3DECL(int) RTTestChangeName(RTTEST hTest, const char *pszName); + /** * Allocate a block of guarded memory. * @@ -294,7 +381,7 @@ RTR3DECL(int) RTTestSubV(RTTEST hTest, const char *pszSubTestFmt, va_list va); /** * Completes a sub-test. * - * @returns Number of chars printed. + * @returns Number of chars printed, negative numbers are IPRT error codes. * @param hTest The test handle. If NIL_RTTEST we'll use the one * associated with the calling thread. */ @@ -306,7 +393,7 @@ RTR3DECL(int) RTTestSubDone(RTTEST hTest); * This does not conclude the sub-test, it could be used to report the passing * of a sub-sub-to-the-power-of-N-test. * - * @returns IPRT status code. + * @returns Number of chars printed, negative numbers are IPRT error codes. * @param hTest The test handle. If NIL_RTTEST we'll use the one * associated with the calling thread. * @param pszFormat The message. No trailing newline. @@ -320,7 +407,7 @@ RTR3DECL(int) RTTestPassedV(RTTEST hTest, const char *pszFormat, va_list va); * This does not conclude the sub-test, it could be used to report the passing * of a sub-sub-to-the-power-of-N-test. * - * @returns IPRT status code. + * @returns Number of chars printed, negative numbers are IPRT error codes. * @param hTest The test handle. If NIL_RTTEST we'll use the one * associated with the calling thread. * @param pszFormat The message. No trailing newline. @@ -328,64 +415,87 @@ RTR3DECL(int) RTTestPassedV(RTTEST hTest, const char *pszFormat, va_list va); */ RTR3DECL(int) RTTestPassed(RTTEST hTest, const char *pszFormat, ...); +/** + * Marks the current test as 'SKIPPED' and optionally displays a message + * explaining why. + * + * @returns Number of chars printed, negative numbers are IPRT error codes. + * @param hTest The test handle. If NIL_RTTEST we'll use the one + * associated with the calling thread. + * @param pszFormat The message. No trailing newline. Can be NULL or empty. + * @param ... The arguments. + */ +RTR3DECL(int) RTTestSkipped(RTTEST hTest, const char *pszFormat, ...); + +/** + * Marks the current test as 'SKIPPED' and optionally displays a message + * explaining why. + * + * @returns Number of chars printed, negative numbers are IPRT error codes. + * @param hTest The test handle. If NIL_RTTEST we'll use the one + * associated with the calling thread. + * @param pszFormat The message. No trailing newline. Can be NULL or empty. + * @param va The arguments. + */ +RTR3DECL(int) RTTestSkippedV(RTTEST hTest, const char *pszFormat, va_list va); + + /** * Value units. + * + * @remarks This is an interface where we have to be binary compatible with both + * older versions of this header and other components using the same + * contant values. + * @remarks When adding a new item: + * - Always add at the end of the list - do NOT group it. + * - Add it to rtTestUnitName in r3/test.cpp. + * - include/VBox/VMMDevTesting.h (VMMDEV_TESTING_UNIT_XXX). + * - Add it to g_aszBs2TestUnitNames in + * TestSuite/bootsectors/bootsector2-common-routines.mac. + * */ typedef enum RTTESTUNIT { - /** The usual invalid value. */ + /** The customary invalid zero value. */ RTTESTUNIT_INVALID = 0, - /** Percentage. */ - RTTESTUNIT_PCT, - /** Bytes. */ - RTTESTUNIT_BYTES, - /** Bytes per second. */ - RTTESTUNIT_BYTES_PER_SEC, - /** Kilobytes. */ - RTTESTUNIT_KILOBYTES, - /** Kilobytes per second. */ - RTTESTUNIT_KILOBYTES_PER_SEC, - /** Megabytes. */ - RTTESTUNIT_MEGABYTES, - /** Megabytes per second. */ - RTTESTUNIT_MEGABYTES_PER_SEC, - /** Packets. */ - RTTESTUNIT_PACKETS, - /** Packets per second. */ - RTTESTUNIT_PACKETS_PER_SEC, - /** Frames. */ - RTTESTUNIT_FRAMES, - /** Frames per second. */ - RTTESTUNIT_FRAMES_PER_SEC, - /** Occurrences. */ - RTTESTUNIT_OCCURRENCES, - /** Occurrences per second. */ - RTTESTUNIT_OCCURRENCES_PER_SEC, - /** Calls. */ - RTTESTUNIT_CALLS, - /** Calls per second. */ - RTTESTUNIT_CALLS_PER_SEC, - /** Round trips. */ - RTTESTUNIT_ROUND_TRIP, - /** Seconds. */ - RTTESTUNIT_SECS, - /** Milliseconds. */ - RTTESTUNIT_MS, - /** Nanoseconds. */ - RTTESTUNIT_NS, - /** Nanoseconds per call. */ - RTTESTUNIT_NS_PER_CALL, - /** Nanoseconds per frame. */ - RTTESTUNIT_NS_PER_FRAME, - /** Nanoseconds per occurrence. */ - RTTESTUNIT_NS_PER_OCCURRENCE, - /** Nanoseconds per frame. */ - RTTESTUNIT_NS_PER_PACKET, - /** Nanoseconds per round trip. */ - RTTESTUNIT_NS_PER_ROUND_TRIP, + + RTTESTUNIT_PCT, /**< Percentage (10^-2). */ + RTTESTUNIT_BYTES, /**< Bytes. */ + RTTESTUNIT_BYTES_PER_SEC, /**< Bytes per second. */ + RTTESTUNIT_KILOBYTES, /**< Kilobytes. */ + RTTESTUNIT_KILOBYTES_PER_SEC, /**< Kilobytes per second. */ + RTTESTUNIT_MEGABYTES, /**< Megabytes. */ + RTTESTUNIT_MEGABYTES_PER_SEC, /**< Megabytes per second. */ + RTTESTUNIT_PACKETS, /**< Packets. */ + RTTESTUNIT_PACKETS_PER_SEC, /**< Packets per second. */ + RTTESTUNIT_FRAMES, /**< Frames. */ + RTTESTUNIT_FRAMES_PER_SEC, /**< Frames per second. */ + RTTESTUNIT_OCCURRENCES, /**< Occurrences. */ + RTTESTUNIT_OCCURRENCES_PER_SEC, /**< Occurrences per second. */ + RTTESTUNIT_CALLS, /**< Calls. */ + RTTESTUNIT_CALLS_PER_SEC, /**< Calls per second. */ + RTTESTUNIT_ROUND_TRIP, /**< Round trips. */ + RTTESTUNIT_SECS, /**< Seconds. */ + RTTESTUNIT_MS, /**< Milliseconds. */ + RTTESTUNIT_NS, /**< Nanoseconds. */ + RTTESTUNIT_NS_PER_CALL, /**< Nanoseconds per call. */ + RTTESTUNIT_NS_PER_FRAME, /**< Nanoseconds per frame. */ + RTTESTUNIT_NS_PER_OCCURRENCE, /**< Nanoseconds per occurrence. */ + RTTESTUNIT_NS_PER_PACKET, /**< Nanoseconds per frame. */ + RTTESTUNIT_NS_PER_ROUND_TRIP, /**< Nanoseconds per round trip. */ + RTTESTUNIT_INSTRS, /**< Instructions. */ + RTTESTUNIT_INSTRS_PER_SEC, /**< Instructions per second. */ + RTTESTUNIT_NONE, /**< No unit. */ + RTTESTUNIT_PP1K, /**< Parts per thousand (10^-3). */ + RTTESTUNIT_PP10K, /**< Parts per ten thousand (10^-4). */ + RTTESTUNIT_PPM, /**< Parts per million (10^-6). */ + RTTESTUNIT_PPB, /**< Parts per billion (10^-9). */ + /** The end of valid units. */ RTTESTUNIT_END } RTTESTUNIT; +AssertCompile(RTTESTUNIT_INSTRS == 0x19); +AssertCompile(RTTESTUNIT_NONE == 0x1b); /** * Report a named test result value. @@ -450,6 +560,15 @@ RTR3DECL(int) RTTestErrorInc(RTTEST hTest); */ RTR3DECL(uint32_t) RTTestErrorCount(RTTEST hTest); +/** + * Get the error count of the current sub test. + * + * @returns The error counter, UINT32_MAX if no valid test handle. + * @param hTest The test handle. If NIL_RTTEST we'll use the one + * associated with the calling thread. + */ +RTR3DECL(uint32_t) RTTestSubErrorCount(RTTEST hTest); + /** * Increments the error counter and prints a failure message. * diff --git a/include/iprt/thread.h b/include/iprt/thread.h index 6bd63b99..35361f80 100644 --- a/include/iprt/thread.h +++ b/include/iprt/thread.h @@ -3,7 +3,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; @@ -533,6 +533,10 @@ typedef struct RTTHREADPREEMPTSTATE /** Reserved, MBZ. */ uint8_t bReserved3; # define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 255, 0, 0, 0 } +# elif defined(RT_OS_HAIKU) + /** The cpu_state. Don't touch! */ + uint32_t uOldCpuState; +# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 } # elif defined(RT_OS_SOLARIS) /** The Old PIL. Don't touch! */ uint32_t uOldPil; @@ -575,6 +579,109 @@ RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState); */ RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread); + +/** + * Thread-context events. + */ +typedef enum RTTHREADCTXEVENT +{ + /** This thread is about to be preempted. */ + RTTHREADCTXEVENT_PREEMPTING = 0, + /** This thread has just been resumed. */ + RTTHREADCTXEVENT_RESUMED, + /** The usual 32-bit size hack. */ + RTTHREADCTXEVENT_32BIT_HACK = 0x7fffffff +} RTTHREADCTXEVENT; + +/** + * Thread-context hook. + * + * @returns IPRT status code. + * @param enmEvent The thread-context event. + * @param pvUser User argument. + * + * @remarks This function may be called under different contexts, i.e. with + * different locks held, with/without preemption disabled depending on + * the event in @a enmEvent. + */ +typedef DECLCALLBACK(void) FNRTTHREADCTXHOOK(RTTHREADCTXEVENT enmEvent, void *pvUser); +/** Pointer to a thread-context hook. */ +typedef FNRTTHREADCTXHOOK *PFNRTTHREADCTXHOOK; + +/** + * Initializes a thread-context hook for the current thread. + * + * This must be called once per-thread before using RTThreadCtxHooksRegister(). + * + * @returns IPRT status code. + * @param phThreadCtx Where to store the thread-context handle. + * + * @remarks This must be called with preemption enabled! + */ +RTDECL(int) RTThreadCtxHooksCreate(PRTTHREADCTX phThreadCtx); + +/** + * Retains a new reference to a thread-context hook. + * + * @returns New reference count. + * UINT32_MAX is returned if the handle is invalid (asserted). + * @param phThreadCtx Pointer to the thread-context handle. + * + * @remarks This can be called from any thread. Can be called with preemption + * disabled. + */ +RTDECL(uint32_t) RTThreadCtxHooksRetain(RTTHREADCTX hThreadCtx); + +/** + * Releases a reference to a thread-context hook. + * + * @returns New reference count. + * @retval 0 if the thread-context hook was freed or @a hThreadCtx is + * NIL_RTTHREADCTX. + * @retval UINT32_MAX is returned if the handle is invalid (asserted). + * + * @param hThreadCtx The thread-context handle. + * + * @remarks This can be called from any thread but must be called with + * preemption enabled! + */ +RTDECL(uint32_t) RTThreadCtxHooksRelease(RTTHREADCTX hThreadCtx); + +/** + * Registers a thread-context hook for the current thread to receive + * notifications for all supported thread-context events. + * + * @returns IPRT status code. + * @param hThreadCtx The thread-context handle. + * @param pfnThreadHook Pointer to a thread-context hook (a callback) + * for all thread-context events. + * @param pvUser User argument (optional, can be NULL). + * + * @remarks Can be called with preemption disabled. + */ +RTDECL(int) RTThreadCtxHooksRegister(RTTHREADCTX hThreadCtx, PFNRTTHREADCTXHOOK pfnThreadHook, void *pvUser); + +/** + * Deregisters the thread-context hook for the current thread. + * + * @returns IPRT status code. + * @param hThreadCtx The thread-context handle. + * + * @remarks Can be called with preemption disabled. + */ +RTDECL(int) RTThreadCtxHooksDeregister(RTTHREADCTX hThreadCtx); + +/** + * Are thread-context hooks registered for the thread? + * + * @returns true if registered, false if not supported or not registered. + * @param hThreadCtx The thread-context handle. + * + * @remarks Can be called from any thread (but possibility of races when + * it's not the current thread!) + */ +RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx); + # endif /* IN_RING0 */ diff --git a/include/iprt/time.h b/include/iprt/time.h index 7a94dcd7..2981d9de 100644 --- a/include/iprt/time.h +++ b/include/iprt/time.h @@ -3,7 +3,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; @@ -524,6 +524,19 @@ DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2) */ RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb); +/** + * Attempts to convert an ISO date string to a time structure. + * + * We're a little forgiving with zero padding, unspecified parts, and leading + * and trailing spaces. + * + * @retval pTime on success, + * @retval NULL on failure. + * @param pTime The time spec. + * @param pszString The ISO date string to convert. + */ +RTDECL(PRTTIMESPEC) RTTimeSpecFromString(PRTTIMESPEC pTime, const char *pszString); + /** @} */ @@ -708,6 +721,19 @@ RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime); */ RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb); +/** + * Attempts to convert an ISO date string to a time structure. + * + * We're a little forgiving with zero padding, unspecified parts, and leading + * and trailing spaces. + * + * @retval pTime on success, + * @retval NULL on failure. + * @param pTime Where to store the time on success. + * @param pszString The ISO date string to convert. + */ +RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString); + /** * Checks if a year is a leap year or not. * diff --git a/include/iprt/types.h b/include/iprt/types.h index e841dea5..3c88ec22 100644 --- a/include/iprt/types.h +++ b/include/iprt/types.h @@ -3,7 +3,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; @@ -165,6 +165,8 @@ RT_C_DECLS_END # include #endif /* no crt */ + + /** @def NULL * NULL pointer. */ @@ -194,9 +196,9 @@ RT_C_DECLS_END #endif /* - * C doesn't have bool. + * C doesn't have bool, nor does VisualAge for C++ v3.08. */ -#ifndef __cplusplus +#if !defined(__cplusplus) || (defined(__IBMCPP__) && defined(RT_OS_OS2)) # if defined(__GNUC__) # if defined(RT_OS_LINUX) && __GNUC__ < 3 typedef uint8_t bool; @@ -205,7 +207,7 @@ typedef uint8_t bool; typedef _Bool bool; # endif # else -# if defined(RT_OS_DARWIN) && defined(_STDBOOL_H) +# if (defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)) && (defined(_STDBOOL_H) || defined(__STDBOOL_H)) # undef bool # endif typedef _Bool bool; @@ -395,6 +397,7 @@ typedef const RTUINT64U *PCRTUINT64U; /** * 128-bit unsigned integer union. */ +#pragma pack(1) typedef union RTUINT128U { /** Natural view. @@ -470,6 +473,7 @@ typedef union RTUINT128U /** 8-bit view. */ uint8_t au8[16]; } RTUINT128U; +#pragma pack() /** Pointer to a 64-bit unsigned integer union. */ typedef RTUINT128U *PRTUINT128U; /** Pointer to a const 64-bit unsigned integer union. */ @@ -546,6 +550,8 @@ typedef RTFLOAT64U *PRTFLOAT64U; typedef const RTFLOAT64U *PCRTFLOAT64U; +#if !defined(__IBMCPP__) && !defined(__IBMC__) + /** * Extended Double precision floating point format (80-bit). */ @@ -690,6 +696,8 @@ typedef RTFLOAT80U2 *PRTFLOAT80U2; * variant. */ typedef const RTFLOAT80U2 *PCRTFLOAT80U2; +#endif /* uint16_t bitfields doesn't work */ + /** Generic function type. * @see PFNRT @@ -733,15 +741,27 @@ typedef const struct RTTIMESPEC *PCRTTIMESPEC; typedef union RTPTRUNION { /** Pointer into the void... */ - void *pv; + void *pv; + /** Pointer to char value. */ + char *pch; + /** Pointer to char value. */ + unsigned char *puch; + /** Pointer to a int value. */ + int *pi; + /** Pointer to a unsigned int value. */ + unsigned int *pu; + /** Pointer to a long value. */ + long *pl; + /** Pointer to a long value. */ + unsigned long *pul; /** Pointer to a 8-bit unsigned value. */ - uint8_t *pu8; + uint8_t *pu8; /** Pointer to a 16-bit unsigned value. */ - uint16_t *pu16; + uint16_t *pu16; /** Pointer to a 32-bit unsigned value. */ - uint32_t *pu32; + uint32_t *pu32; /** Pointer to a 64-bit unsigned value. */ - uint64_t *pu64; + uint64_t *pu64; } RTPTRUNION; /** Pointer to a pointer union. */ typedef RTPTRUNION *PRTPTRUNION; @@ -752,15 +772,27 @@ typedef RTPTRUNION *PRTPTRUNION; typedef union RTCPTRUNION { /** Pointer into the void... */ - void const *pv; + void const *pv; + /** Pointer to char value. */ + char const *pch; + /** Pointer to char value. */ + unsigned char const *puch; + /** Pointer to a int value. */ + int const *pi; + /** Pointer to a unsigned int value. */ + unsigned int const *pu; + /** Pointer to a long value. */ + long const *pl; + /** Pointer to a long value. */ + unsigned long const *pul; /** Pointer to a 8-bit unsigned value. */ - uint8_t const *pu8; + uint8_t const *pu8; /** Pointer to a 16-bit unsigned value. */ - uint16_t const *pu16; + uint16_t const *pu16; /** Pointer to a 32-bit unsigned value. */ - uint32_t const *pu32; + uint32_t const *pu32; /** Pointer to a 64-bit unsigned value. */ - uint64_t const *pu64; + uint64_t const *pu64; } RTCPTRUNION; /** Pointer to a const pointer union. */ typedef RTCPTRUNION *PRTCPTRUNION; @@ -771,15 +803,27 @@ typedef RTCPTRUNION *PRTCPTRUNION; typedef union RTVPTRUNION { /** Pointer into the void... */ - void volatile *pv; + void volatile *pv; + /** Pointer to char value. */ + char volatile *pch; + /** Pointer to char value. */ + unsigned char volatile *puch; + /** Pointer to a int value. */ + int volatile *pi; + /** Pointer to a unsigned int value. */ + unsigned int volatile *pu; + /** Pointer to a long value. */ + long volatile *pl; + /** Pointer to a long value. */ + unsigned long volatile *pul; /** Pointer to a 8-bit unsigned value. */ - uint8_t volatile *pu8; + uint8_t volatile *pu8; /** Pointer to a 16-bit unsigned value. */ - uint16_t volatile *pu16; + uint16_t volatile *pu16; /** Pointer to a 32-bit unsigned value. */ - uint32_t volatile *pu32; + uint32_t volatile *pu32; /** Pointer to a 64-bit unsigned value. */ - uint64_t volatile *pu64; + uint64_t volatile *pu64; } RTVPTRUNION; /** Pointer to a const pointer union. */ typedef RTVPTRUNION *PRTVPTRUNION; @@ -790,15 +834,27 @@ typedef RTVPTRUNION *PRTVPTRUNION; typedef union RTCVPTRUNION { /** Pointer into the void... */ - void const volatile *pv; + void const volatile *pv; + /** Pointer to char value. */ + char const volatile *pch; + /** Pointer to char value. */ + unsigned char const volatile *puch; + /** Pointer to a int value. */ + int const volatile *pi; + /** Pointer to a unsigned int value. */ + unsigned int const volatile *pu; + /** Pointer to a long value. */ + long const volatile *pl; + /** Pointer to a long value. */ + unsigned long const volatile *pul; /** Pointer to a 8-bit unsigned value. */ - uint8_t const volatile *pu8; + uint8_t const volatile *pu8; /** Pointer to a 16-bit unsigned value. */ - uint16_t const volatile *pu16; + uint16_t const volatile *pu16; /** Pointer to a 32-bit unsigned value. */ - uint32_t const volatile *pu32; + uint32_t const volatile *pu32; /** Pointer to a 64-bit unsigned value. */ - uint64_t const volatile *pu64; + uint64_t const volatile *pu64; } RTCVPTRUNION; /** Pointer to a const pointer union. */ typedef RTCVPTRUNION *PRTCVPTRUNION; @@ -1585,6 +1641,11 @@ typedef struct RTCRITSECT *PRTCRITSECT; /** Pointer to a const critical section. */ typedef const struct RTCRITSECT *PCRTCRITSECT; +/** Pointer to a read/write critical section. */ +typedef struct RTCRITSECTRW *PRTCRITSECTRW; +/** Pointer to a const read/write critical section. */ +typedef const struct RTCRITSECTRW *PCRTCRITSECTRW; + /** Condition variable handle. */ typedef R3PTRTYPE(struct RTCONDVARINTERNAL *) RTCONDVAR; @@ -1763,6 +1824,13 @@ typedef RTTHREAD *PRTTHREAD; /** Nil thread handle. */ #define NIL_RTTHREAD 0 +/** Thread-context handle.*/ +typedef R0PTRTYPE(struct RTTHREADCTXINT *) RTTHREADCTX; +/** Pointer to thread handle. */ +typedef RTTHREADCTX *PRTTHREADCTX; +/** Nil thread-context handle. */ +#define NIL_RTTHREADCTX 0 + /** A TLS index. */ typedef RTHCINTPTR RTTLS; /** Pointer to a TLS index. */ @@ -1952,6 +2020,19 @@ typedef RTVFSSYMLINK *PRTVFSSYMLINK; /** A NIL VFS symbolic link handle. */ #define NIL_RTVFSSYMLINK ((RTVFSSYMLINK)~(uintptr_t)0) +/** Async I/O manager handle. */ +typedef struct RTAIOMGRINT *RTAIOMGR; +/** Pointer to a async I/O manager handle. */ +typedef RTAIOMGR *PRTAIOMGR; +/** A NIL async I/O manager handle. */ +#define NIL_RTAIOMGR ((RTAIOMGR)~(uintptr_t)0) + +/** Async I/O manager file handle. */ +typedef struct RTAIOMGRFILEINT *RTAIOMGRFILE; +/** Pointer to a async I/O manager file handle. */ +typedef RTAIOMGRFILE *PRTAIOMGRFILE; +/** A NIL async I/O manager file handle. */ +#define NIL_RTAIOMGRFILE ((RTAIOMGRFILE)~(uintptr_t)0) /** * Handle type. @@ -2111,6 +2192,9 @@ typedef RTUUID *PRTUUID; /** Pointer to readonly UUID data. */ typedef const RTUUID *PCRTUUID; +/** Initializes a RTUUID structure with all zeros (RTUuidIsNull() true). */ +#define RTUUID_INITIALIZE_NULL { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } + /** UUID string maximum length. */ #define RTUUID_STR_LENGTH 37 @@ -2273,6 +2357,9 @@ typedef const RTMAC *PCRTMAC; /** Pointer to a lock validator record. * The structure definition is found in iprt/lockvalidator.h. */ typedef struct RTLOCKVALRECEXCL *PRTLOCKVALRECEXCL; +/** Pointer to a record of one ownership share. + * The structure definition is found in iprt/lockvalidator.h. */ +typedef struct RTLOCKVALRECSHRD *PRTLOCKVALRECSHRD; /** Pointer to a lock validator source poisition. * The structure definition is found in iprt/lockvalidator.h. */ typedef struct RTLOCKVALSRCPOS *PRTLOCKVALSRCPOS; diff --git a/include/iprt/uni.h b/include/iprt/uni.h index 6f0c23ec..a1161db1 100644 --- a/include/iprt/uni.h +++ b/include/iprt/uni.h @@ -3,7 +3,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; @@ -46,8 +46,8 @@ RT_C_DECLS_BEGIN - #ifndef RTUNI_USE_WCTYPE + /** * A unicode flags range. * @internal @@ -160,6 +160,20 @@ DECLINLINE(bool) RTUniCpIsLower(RTUNICP CodePoint) } +/** + * Checks if a unicode code point is case foldable. + * + * @returns true if it is. + * @returns false if it isn't. + * @param CodePoint The code point. + */ +DECLINLINE(bool) RTUniCpIsFoldable(RTUNICP CodePoint) +{ + /* Right enough. */ + return (rtUniCpFlags(CodePoint) & (RTUNI_LOWER | RTUNI_UPPER)) != 0; +} + + /** * Checks if a unicode code point is alphabetic. * @@ -302,6 +316,20 @@ DECLINLINE(bool) RTUniCpIsLower(RTUNICP CodePoint) } +/** + * Checks if a unicode code point is case foldable. + * + * @returns true if it is. + * @returns false if it isn't. + * @param CodePoint The code point. + */ +DECLINLINE(bool) RTUniCpIsFoldable(RTUNICP CodePoint) +{ + /* Right enough. */ + return iswupper(CodePoint) || iswlower(CodePoint); +} + + /** * Checks if a unicode code point is alphabetic. * diff --git a/include/iprt/uuid.h b/include/iprt/uuid.h index 94604e2b..1a9c9750 100644 --- a/include/iprt/uuid.h +++ b/include/iprt/uuid.h @@ -3,7 +3,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/include/iprt/vfs.h b/include/iprt/vfs.h index 6eefa01d..787c1b39 100644 --- a/include/iprt/vfs.h +++ b/include/iprt/vfs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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; @@ -332,7 +332,7 @@ RTDECL(uint32_t) RTVfsDirRelease(RTVFSDIR hVfsDir); /** @} */ -/** @defgroup grp_vfs_iostream VFS Symbolic Link API +/** @defgroup grp_vfs_symlink VFS Symbolic Link API * * @remarks The TAR VFS and filesystem stream uses symbolic links for * describing hard links as well. The users must use RTFS_IS_SYMLINK @@ -451,6 +451,17 @@ RTDECL(int) RTVfsSymlinkRead(RTVFSSYMLINK hVfsSym, char *pszTarget, size */ RTDECL(int) RTVfsIoStrmFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos); +/** + * Convenience function combining RTFileOpen with RTVfsIoStrmFromRTFile. + * + * @returns IPRT status code. + * @param pszFilename The path to the file in the normal file system. + * @param fOpen The flags to pass to RTFileOpen when opening the + * file, i.e. RTFILE_O_XXX. + * @param phVfsIos Where to return the VFS I/O stream handle. + */ +RTDECL(int) RTVfsIoStrmOpenNormal(const char *pszFilename, uint64_t fOpen, PRTVFSIOSTREAM phVfsIos); + /** * Create a VFS I/O stream handle from one of the standard handles. * @@ -594,7 +605,7 @@ RTDECL(int) RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, b * attemted written. * @param fBlocking Whether the call is blocking (@c true) or not. If * not, the @a pcbWritten parameter must not be NULL. - * @param pcbRead Where to always store the number of bytes actually + * @param pcbWritten Where to always store the number of bytes actually * written. This can be NULL if @a fBlocking is true. * @sa RTFileSgWrite, RTSocketSgWrite */ @@ -704,6 +715,17 @@ RTDECL(int) RTVfsFileOpen(RTVFS hVfs, const char *pszFilename, uint64_t RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile); RTDECL(RTHCUINTPTR) RTVfsFileToNative(RTFILE hVfsFile); +/** + * Convenience function combining RTFileOpen with RTVfsFileFromRTFile. + * + * @returns IPRT status code. + * @param pszFilename The path to the file in the normal file system. + * @param fOpen The flags to pass to RTFileOpen when opening the + * file, i.e. RTFILE_O_XXX. + * @param phVfsFile Where to return the VFS file handle. + */ +RTDECL(int) RTVfsFileOpenNormal(const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile); + /** * Convert the VFS file handle to a VFS I/O stream handle. * diff --git a/include/iprt/vfslowlevel.h b/include/iprt/vfslowlevel.h index d5208cf4..c077016e 100644 --- a/include/iprt/vfslowlevel.h +++ b/include/iprt/vfslowlevel.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-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/include/iprt/win/lazy-dbghelp.h b/include/iprt/win/lazy-dbghelp.h new file mode 100644 index 00000000..6232e909 --- /dev/null +++ b/include/iprt/win/lazy-dbghelp.h @@ -0,0 +1,137 @@ +/** @file + * Symbols from dbghelp.dll, allowing us to select which one to load. + */ + +/* + * 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 ___iprt_win_lazy_dbghelp_h +#define ___iprt_win_lazy_dbghelp_h + +#include +#include +#include + + +/** + * Custom loader callback. + * @returns Module handle or NIL_RTLDRMOD. + */ +static int rtLdrLazyLoadDbgHelp(const char *pszFile, PRTLDRMOD phMod) +{ + static const struct + { + const char *pszEnv; + const char *pszSubDir; + } s_aLocations[] = + { +#ifdef RT_ARCH_AMD64 + { "ProgramFiles(x86)", "Windows Kits\\8.1\\Debuggers\\x64\\dbghelp.dll" }, + { "ProgramFiles(x86)", "Windows Kits\\8.0\\Debuggers\\x64\\dbghelp.dll" }, + { "ProgramFiles", "Debugging Tools for Windows (x64)\\dbghelp.dll" }, +#else + { "ProgramFiles", "Windows Kits\\8.1\\Debuggers\\x86\\dbghelp.dll" }, + { "ProgramFiles", "Windows Kits\\8.0\\Debuggers\\x86\\dbghelp.dll" }, + { "ProgramFiles", "Debugging Tools for Windows (x86)\\dbghelp.dll" }, +#endif /** @todo More places we should look? */ + }; + uint32_t i; + for (i = 0; i < RT_ELEMENTS(s_aLocations); i++) + { + char szPath[RTPATH_MAX]; + size_t cchPath; + int rc = RTEnvGetEx(RTENV_DEFAULT, s_aLocations[i].pszEnv, szPath, sizeof(szPath), &cchPath); + if (RT_SUCCESS(rc)) + { + rc = RTPathAppend(szPath, sizeof(szPath), s_aLocations[i].pszSubDir); + if (RT_SUCCESS(rc)) + { + rc = RTLdrLoad(szPath, phMod); + if (RT_SUCCESS(rc)) + return rc; + } + } + } + + /* Fall back on the system one, if present. */ + return RTLdrLoadSystem(pszFile, true /*fNoUnload*/, phMod); +} + +RTLDRLAZY_MODULE_EX(dbghelp, "dbghelp.dll", rtLdrLazyLoadDbgHelp); + +RTLDRLAZY_FUNC(dbghelp, BOOL, WINAPI, SymInitialize, (HANDLE a1, PCWSTR a2, BOOL a3), (a1, a2, a3), FALSE); +#undef SymInitialize +#define SymInitialize RTLDRLAZY_FUNC_NAME(dbghelp, SymInitialize) + +RTLDRLAZY_FUNC(dbghelp, BOOL, WINAPI, SymCleanup, (HANDLE a1), (a1), FALSE); +#undef SymCleanup +#define SymCleanup RTLDRLAZY_FUNC_NAME(dbghelp, SymCleanup) + +RTLDRLAZY_FUNC(dbghelp, DWORD, WINAPI, SymGetOptions, (VOID), (), 0); +#undef SymGetOptions +#define SymGetOptions RTLDRLAZY_FUNC_NAME(dbghelp, SymGetOptions) + +RTLDRLAZY_FUNC(dbghelp, DWORD, WINAPI, SymSetOptions, (DWORD a1), (a1), 0); +#undef SymSetOptions +#define SymSetOptions RTLDRLAZY_FUNC_NAME(dbghelp, SymSetOptions) + +RTLDRLAZY_FUNC(dbghelp, BOOL, WINAPI, SymRegisterCallback64, (HANDLE a1, PSYMBOL_REGISTERED_CALLBACK64 a2, ULONG64 a3), + (a1, a2, a3), FALSE); +#undef SymRegisterCallback64 +#define SymRegisterCallback64 RTLDRLAZY_FUNC_NAME(dbghelp, SymRegisterCallback64) + +RTLDRLAZY_FUNC(dbghelp, DWORD64, WINAPI, SymLoadModuleEx, + (HANDLE a1, HANDLE a2, PCSTR a3, PCSTR a4, DWORD64 a5, DWORD a6, PMODLOAD_DATA a7, DWORD a8), + (a1, a2, a3, a4, a5, a6, a7, a8), 0); +#undef SymLoadModuleEx +#define SymLoadModuleEx RTLDRLAZY_FUNC_NAME(dbghelp, SymLoadModuleEx) + +RTLDRLAZY_FUNC(dbghelp, DWORD64, WINAPI, SymLoadModuleExW, + (HANDLE a1, HANDLE a2, PCWSTR a3, PCWSTR a4, DWORD64 a5, DWORD a6, PMODLOAD_DATA a7, DWORD a8), + (a1, a2, a3, a4, a5, a6, a7, a8), 0); +#undef SymLoadModuleExW +#define SymLoadModuleExW RTLDRLAZY_FUNC_NAME(dbghelp, SymLoadModuleExW) + +RTLDRLAZY_FUNC(dbghelp, DWORD64, WINAPI, SymUnloadModule64, (HANDLE a1, DWORD64 a2), (a1, a2), 0); +#undef SymUnloadModule64 +#define SymUnloadModule64 RTLDRLAZY_FUNC_NAME(dbghelp, SymUnloadModule64) + +RTLDRLAZY_FUNC(dbghelp, BOOL, WINAPI, SymEnumSymbols, + (HANDLE a1, ULONG64 a2, PCSTR a3, PSYM_ENUMERATESYMBOLS_CALLBACK a4, PVOID a5), + (a1, a2, a3, a4, a5), FALSE); +#undef SymEnumSymbols +#define SymEnumSymbols RTLDRLAZY_FUNC_NAME(dbghelp, SymEnumSymbols) + +RTLDRLAZY_FUNC(dbghelp, BOOL, WINAPI, SymEnumLinesW, + (HANDLE a1, ULONG64 a2, PCWSTR a3, PCWSTR a4, PSYM_ENUMLINES_CALLBACKW a5, PVOID a6), + (a1, a2, a3, a4, a5, a6), FALSE); +#undef SymEnumLinesW +#define SymEnumLinesW RTLDRLAZY_FUNC_NAME(dbghelp, SymEnumLinesW) + +RTLDRLAZY_FUNC(dbghelp, BOOL, WINAPI, SymGetModuleInfo64, (HANDLE a1, DWORD64 a2, PIMAGEHLP_MODULE64 a3), (a1, a2, a3), FALSE); +#undef SymGetModuleInfo64 +#define SymGetModuleInfo64 RTLDRLAZY_FUNC_NAME(dbghelp, SymGetModuleInfo64) + + + + +#endif + diff --git a/include/iprt/x86.h b/include/iprt/x86.h index 22b0b952..204a2ec1 100644 --- a/include/iprt/x86.h +++ b/include/iprt/x86.h @@ -161,16 +161,20 @@ typedef const X86RFLAGS *PCX86RFLAGS; */ /** Bit 0 - CF - Carry flag - Status flag. */ #define X86_EFL_CF RT_BIT(0) +#define X86_EFL_CF_BIT 0 /** Bit 1 - Reserved, reads as 1. */ #define X86_EFL_1 RT_BIT(1) /** Bit 2 - PF - Parity flag - Status flag. */ #define X86_EFL_PF RT_BIT(2) /** Bit 4 - AF - Auxiliary carry flag - Status flag. */ #define X86_EFL_AF RT_BIT(4) +#define X86_EFL_AF_BIT 4 /** Bit 6 - ZF - Zero flag - Status flag. */ #define X86_EFL_ZF RT_BIT(6) +#define X86_EFL_ZF_BIT 6 /** Bit 7 - SF - Signed flag - Status flag. */ #define X86_EFL_SF RT_BIT(7) +#define X86_EFL_SF_BIT 7 /** Bit 8 - TF - Trap flag - System flag. */ #define X86_EFL_TF RT_BIT(8) /** Bit 9 - IF - Interrupt flag - System flag. */ @@ -179,6 +183,7 @@ typedef const X86RFLAGS *PCX86RFLAGS; #define X86_EFL_DF RT_BIT(10) /** Bit 11 - OF - Overflow flag - Status flag. */ #define X86_EFL_OF RT_BIT(11) +#define X86_EFL_OF_BIT 11 /** Bit 12-13 - IOPL - I/O prvilege level flag - System flag. */ #define X86_EFL_IOPL (RT_BIT(12) | RT_BIT(13)) /** Bit 14 - NT - Nested task flag - System flag. */ @@ -195,12 +200,19 @@ typedef const X86RFLAGS *PCX86RFLAGS; #define X86_EFL_VIP RT_BIT(20) /** Bit 21 - ID - CPUID flag - System flag. If this responds to flipping CPUID is supported. */ #define X86_EFL_ID RT_BIT(21) +/** All live bits. */ +#define X86_EFL_LIVE_MASK UINT32_C(0x003f7fd5) +/** Read as 1 bits. */ +#define X86_EFL_RA1_MASK RT_BIT_32(1) /** IOPL shift. */ #define X86_EFL_IOPL_SHIFT 12 /** The the IOPL level from the flags. */ #define X86_EFL_GET_IOPL(efl) (((efl) >> X86_EFL_IOPL_SHIFT) & 3) /** Bits restored by popf */ -#define X86_EFL_POPF_BITS (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID) +#define X86_EFL_POPF_BITS ( X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF \ + | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID ) +/** The status bits commonly updated by arithmetic instructions. */ +#define X86_EFL_STATUS_BITS ( X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF ) /** @} */ @@ -437,6 +449,8 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; #define X86_CPUID_FEATURE_ECX_OSXSAVE RT_BIT(27) /** ECX Bit 28 - AVX. */ #define X86_CPUID_FEATURE_ECX_AVX RT_BIT(28) +/** ECX Bit 29 - F16C - Half-precision convert instruction support. */ +#define X86_CPUID_FEATURE_ECX_F16C RT_BIT(29) /** ECX Bit 31 - Hypervisor Present (software only). */ #define X86_CPUID_FEATURE_ECX_HVP RT_BIT(31) @@ -736,6 +750,8 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; #define X86_DR6_B2 RT_BIT(2) /** Bit 3 - B3 - Breakpoint 3 condition detected. */ #define X86_DR6_B3 RT_BIT(3) +/** Mask of all the Bx bits. */ +#define X86_DR6_B_MASK UINT64_C(0x0000000f) /** Bit 13 - BD - Debug register access detected. Corresponds to the X86_DR7_GD bit. */ #define X86_DR6_BD RT_BIT(13) /** Bit 14 - BS - Single step */ @@ -744,8 +760,17 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; #define X86_DR6_BT RT_BIT(15) /** Value of DR6 after powerup/reset. */ #define X86_DR6_INIT_VAL UINT64_C(0xFFFF0FF0) +/** Bits which must be 1s in DR6. */ +#define X86_DR6_RA1_MASK UINT64_C(0xffff0ff0) +/** Bits which must be 0s in DR6. */ +#define X86_DR6_RAZ_MASK RT_BIT_64(12) +/** Bits which must be 0s on writes to DR6. */ +#define X86_DR6_MBZ_MASK UINT64_C(0xffffffff00000000) /** @} */ +/** Get the DR6.Bx bit for a the given breakpoint. */ +#define X86_DR6_B(iBp) RT_BIT_64(iBp) + /** @name DR7 * @{ */ @@ -770,6 +795,11 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** Bit 9 - GE - Local breakpoint exact. (Not supported (read ignored) by P6 and later.) */ #define X86_DR7_GE RT_BIT(9) +/** L0, L1, L2, and L3. */ +#define X86_DR7_LE_ALL UINT64_C(0x0000000000000055) +/** L0, L1, L2, and L3. */ +#define X86_DR7_GE_ALL UINT64_C(0x00000000000000aa) + /** Bit 13 - GD - General detect enable. Enables emulators to get exceptions when * any DR register is accessed. */ #define X86_DR7_GD RT_BIT(13) @@ -790,8 +820,12 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** Bit 30 & 31 - LEN3 - Length field 0. Values X86_DR7_LEN_*. */ #define X86_DR7_LEN3_MASK (3 << 30) -/** Bits which must be 1s. */ -#define X86_DR7_MB1_MASK (RT_BIT(10)) +/** Bits which reads as 1s. */ +#define X86_DR7_RA1_MASK (RT_BIT(10)) +/** Bits which reads as zeros. */ +#define X86_DR7_RAZ_MASK UINT64_C(0x0000d800) +/** Bits which must be 0s when writing to DR7. */ +#define X86_DR7_MBZ_MASK UINT64_C(0xffffffff00000000) /** Calcs the L bit of Nth breakpoint. * @param iBp The breakpoint number [0..3]. @@ -803,6 +837,11 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; */ #define X86_DR7_G(iBp) ( UINT32_C(1) << (iBp * 2 + 1) ) +/** Calcs the L and G bits of Nth breakpoint. + * @param iBp The breakpoint number [0..3]. + */ +#define X86_DR7_L_G(iBp) ( UINT32_C(3) << (iBp * 2) ) + /** @name Read/Write values. * @{ */ /** Break on instruction fetch only. */ @@ -821,6 +860,33 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; */ #define X86_DR7_RW(iBp, fRw) ( (fRw) << ((iBp) * 4 + 16) ) +/** Fetch the the R/Wx bits for a given breakpoint (so it can be compared with + * one of the X86_DR7_RW_XXX constants). + * + * @returns X86_DR7_RW_XXX + * @param uDR7 DR7 value + * @param iBp The breakpoint number [0..3]. + */ +#define X86_DR7_GET_RW(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 16) ) & UINT32_C(3) ) + +/** R/W0, R/W1, R/W2, and R/W3. */ +#define X86_DR7_RW_ALL_MASKS UINT32_C(0x33330000) + +/** Checks if there are any I/O breakpoint types configured in the RW + * registers. Does NOT check if these are enabled, sorry. */ +#define X86_DR7_ANY_RW_IO(uDR7) \ + ( ( UINT32_C(0x22220000) & (uDR7) ) /* any candidates? */ \ + && ( ( (UINT32_C(0x22220000) & (uDR7) ) >> 1 ) & ~(uDR7) ) ) +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x33330000)) == 0); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x22220000)) == 1); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x32320000)) == 1); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x23230000)) == 1); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00000000)) == 0); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00010000)) == 0); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00020000)) == 1); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00030000)) == 0); +AssertCompile(X86_DR7_ANY_RW_IO(UINT32_C(0x00040000)) == 0); + /** @name Length values. * @{ */ #define X86_DR7_LEN_BYTE 0U @@ -839,13 +905,15 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; * @param uDR7 DR7 value * @param iBp The breakpoint number [0..3]. */ -#define X86_DR7_GET_LEN(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 18) ) & 0x3U) +#define X86_DR7_GET_LEN(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 18) ) & UINT32_C(0x3) ) /** Mask used to check if any breakpoints are enabled. */ -#define X86_DR7_ENABLED_MASK (RT_BIT(0) | RT_BIT(1) | RT_BIT(2) | RT_BIT(3) | RT_BIT(4) | RT_BIT(5) | RT_BIT(6) | RT_BIT(7)) +#define X86_DR7_ENABLED_MASK UINT32_C(0x000000ff) -/** Mask used to check if any io breakpoints are set. */ -#define X86_DR7_IO_ENABLED_MASK (X86_DR7_RW(0, X86_DR7_RW_IO) | X86_DR7_RW(1, X86_DR7_RW_IO) | X86_DR7_RW(2, X86_DR7_RW_IO) | X86_DR7_RW(3, X86_DR7_RW_IO)) +/** LEN0, LEN1, LEN2, and LEN3. */ +#define X86_DR7_LEN_ALL_MASKS UINT32_C(0xcccc0000) +/** R/W0, R/W1, R/W2, R/W3,LEN0, LEN1, LEN2, and LEN3. */ +#define X86_DR7_RW_LEN_ALL_MASKS UINT32_C(0xffff0000) /** Value of DR7 after powerup/reset. */ #define X86_DR7_INIT_VAL 0x400 @@ -855,19 +923,41 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** @name Machine Specific Registers * @{ */ - +/** Machine check address register (P5). */ +#define MSR_P5_MC_ADDR UINT32_C(0x00000000) +/** Machine check type register (P5). */ +#define MSR_P5_MC_TYPE UINT32_C(0x00000001) /** Time Stamp Counter. */ #define MSR_IA32_TSC 0x10 +#define MSR_IA32_CESR UINT32_C(0x00000011) +#define MSR_IA32_CTR0 UINT32_C(0x00000012) +#define MSR_IA32_CTR1 UINT32_C(0x00000013) #define MSR_IA32_PLATFORM_ID 0x17 #ifndef MSR_IA32_APICBASE /* qemu cpu.h kludge */ -#define MSR_IA32_APICBASE 0x1b +# define MSR_IA32_APICBASE 0x1b +/** Local APIC enabled. */ +# define MSR_IA32_APICBASE_EN RT_BIT_64(11) +/** X2APIC enabled (requires the EN bit to be set). */ +# define MSR_IA32_APICBASE_EXTD RT_BIT_64(10) +/** The processor is the boot strap processor (BSP). */ +# define MSR_IA32_APICBASE_BSP RT_BIT_64(8) +/** Minimum base address mask, consult CPUID leaf 0x80000008 for the actual + * width. */ +# define MSR_IA32_APICBASE_BASE_MIN UINT64_C(0x0000000ffffff000) #endif +/** Undocumented intel MSR for reporting thread and core counts. + * Judging from the XNU sources, it seems to be introduced in Nehalem. The + * first 16 bits is the thread count. The next 16 bits the core count, except + * on Westmere where it seems it's only the next 4 bits for some reason. */ +#define MSR_CORE_THREAD_COUNT 0x35 + /** CPU Feature control. */ #define MSR_IA32_FEATURE_CONTROL 0x3A #define MSR_IA32_FEATURE_CONTROL_LOCK RT_BIT(0) +#define MSR_IA32_FEATURE_CONTROL_SMX_VMXON RT_BIT(1) #define MSR_IA32_FEATURE_CONTROL_VMXON RT_BIT(2) /** BIOS update trigger (microcode update). */ @@ -891,9 +981,19 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** Get FSB clock status (Intel-specific). */ #define MSR_IA32_FSB_CLOCK_STS 0xCD +/** C-State configuration control. Intel specific: Nehalem, Sandy Bridge. */ +#define MSR_PKG_CST_CONFIG_CONTROL UINT32_C(0x000000e2) + +/** C0 Maximum Frequency Clock Count */ +#define MSR_IA32_MPERF 0xE7 +/** C0 Actual Frequency Clock Count */ +#define MSR_IA32_APERF 0xE8 + /** MTRR Capabilities. */ #define MSR_IA32_MTRR_CAP 0xFE +/** Cache control/info. */ +#define MSR_BBL_CR_CTL3 UINT32_C(0x11e) #ifndef MSR_IA32_SYSENTER_CS /* qemu cpu.h kludge */ /** SYSENTER_CS - the R0 CS, indirectly giving R0 SS, R3 CS and R3 DS. @@ -909,14 +1009,11 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; #endif /** Machine Check Global Capabilities Register. */ -#define MSR_IA32_MCP_CAP 0x179 +#define MSR_IA32_MCG_CAP 0x179 /** Machine Check Global Status Register. */ -#define MSR_IA32_MCP_STATUS 0x17A +#define MSR_IA32_MCG_STATUS 0x17A /** Machine Check Global Control Register. */ -#define MSR_IA32_MCP_CTRL 0x17B - -/** Trace/Profile Resource Control (R/W) */ -#define MSR_IA32_DEBUGCTL 0x1D9 +#define MSR_IA32_MCG_CTRL 0x17B /** Page Attribute Table. */ #define MSR_IA32_CR_PAT 0x277 @@ -924,7 +1021,14 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** Performance counter MSRs. (Intel only) */ #define MSR_IA32_PERFEVTSEL0 0x186 #define MSR_IA32_PERFEVTSEL1 0x187 -#define MSR_IA32_FLEX_RATIO 0x194 +/** Flexible ratio, seems to be undocumented, used by XNU (tsc.c). + * The 16th bit whether flex ratio is being used, in which case bits 15:8 + * holds a ratio that Apple takes for TSC granularity. + * + * @note This MSR conflics the P4 MSR_MCG_R12 register. */ +#define MSR_FLEX_RATIO 0x194 +/** Performance state value and starting with Intel core more. + * Apple uses the >=core features to determine TSC granularity on older CPUs. */ #define MSR_IA32_PERF_STATUS 0x198 #define MSR_IA32_PERF_CTL 0x199 #define MSR_IA32_THERM_STATUS 0x19c @@ -932,25 +1036,39 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** Enable misc. processor features (R/W). */ #define MSR_IA32_MISC_ENABLE 0x1A0 /** Enable fast-strings feature (for REP MOVS and REP STORS). */ -#define MSR_IA32_MISC_ENABLE_FAST_STRINGS RT_BIT(0) +#define MSR_IA32_MISC_ENABLE_FAST_STRINGS RT_BIT_64(0) /** Automatic Thermal Control Circuit Enable (R/W). */ -#define MSR_IA32_MISC_ENABLE_TCC RT_BIT(3) +#define MSR_IA32_MISC_ENABLE_TCC RT_BIT_64(3) /** Performance Monitoring Available (R). */ -#define MSR_IA32_MISC_ENABLE_PERF_MON RT_BIT(7) +#define MSR_IA32_MISC_ENABLE_PERF_MON RT_BIT_64(7) /** Branch Trace Storage Unavailable (R/O). */ -#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL RT_BIT(11) +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL RT_BIT_64(11) /** Precise Event Based Sampling (PEBS) Unavailable (R/O). */ -#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL RT_BIT(12) +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL RT_BIT_64(12) /** Enhanced Intel SpeedStep Technology Enable (R/W). */ -#define MSR_IA32_MISC_ENABLE_SST_ENABLE RT_BIT(16) +#define MSR_IA32_MISC_ENABLE_SST_ENABLE RT_BIT_64(16) /** If MONITOR/MWAIT is supported (R/W). */ -#define MSR_IA32_MISC_ENABLE_MONITOR RT_BIT(18) +#define MSR_IA32_MISC_ENABLE_MONITOR RT_BIT_64(18) /** Limit CPUID Maxval to 3 leafs (R/W). */ -#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID RT_BIT(22) +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID RT_BIT_64(22) /** When set to 1, xTPR messages are disabled (R/W). */ -#define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE RT_BIT(23) +#define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE RT_BIT_64(23) /** When set to 1, the Execute Disable Bit feature (XD Bit) is disabled (R/W). */ -#define MSR_IA32_MISC_ENABLE_XD_DISABLE RT_BIT(34) +#define MSR_IA32_MISC_ENABLE_XD_DISABLE RT_BIT_64(34) + +/** Trace/Profile Resource Control (R/W) */ +#define MSR_IA32_DEBUGCTL UINT32_C(0x000001d9) +/** The number (0..3 or 0..15) of the last branch record register on P4 and + * related Xeons. */ +#define MSR_P4_LASTBRANCH_TOS UINT32_C(0x000001da) +/** @name Last branch registers for P4 and Xeon, models 0 thru 2. + * @{ */ +#define MSR_P4_LASTBRANCH_0 UINT32_C(0x000001db) +#define MSR_P4_LASTBRANCH_1 UINT32_C(0x000001dc) +#define MSR_P4_LASTBRANCH_2 UINT32_C(0x000001dd) +#define MSR_P4_LASTBRANCH_3 UINT32_C(0x000001de) +/** @} */ + #define IA32_MTRR_PHYSBASE0 0x200 #define IA32_MTRR_PHYSMASK0 0x201 @@ -1016,18 +1134,23 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; #define MSR_IA32_VMX_CR4_FIXED1 0x489 /** Information for enumerating fields in the VMCS. */ #define MSR_IA32_VMX_VMCS_ENUM 0x48A +/** Allowed settings for the VM-functions controls. */ +#define MSR_IA32_VMX_VMFUNC 0x491 /** Allowed settings for secondary proc-based VM execution controls */ #define MSR_IA32_VMX_PROCBASED_CTLS2 0x48B /** EPT capabilities. */ -#define MSR_IA32_VMX_EPT_CAPS 0x48C +#define MSR_IA32_VMX_EPT_VPID_CAP 0x48C /** DS Save Area (R/W). */ #define MSR_IA32_DS_AREA 0x600 +/** Running Average Power Limit (RAPL) power units. */ +#define MSR_RAPL_POWER_UNIT 0x606 /** X2APIC MSR ranges. */ -#define MSR_IA32_APIC_START 0x800 -#define MSR_IA32_APIC_END 0x900 +#define MSR_IA32_X2APIC_START 0x800 +#define MSR_IA32_X2APIC_TPR 0x808 +#define MSR_IA32_X2APIC_END 0xBFF /** K6 EFER - Extended Feature Enable Register. */ -#define MSR_K6_EFER 0xc0000080 +#define MSR_K6_EFER UINT32_C(0xc0000080) /** @todo document EFER */ /** Bit 0 - SCE - System call extensions (SYSCALL / SYSRET). (R/W) */ #define MSR_K6_EFER_SCE RT_BIT(0) @@ -1044,65 +1167,71 @@ typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX; /** Bit 14 - FFXSR - Fast FXSAVE / FXRSTOR (skip XMM*). (R/W) */ #define MSR_K6_EFER_FFXSR RT_BIT(14) /** K6 STAR - SYSCALL/RET targets. */ -#define MSR_K6_STAR 0xc0000081 +#define MSR_K6_STAR UINT32_C(0xc0000081) /** Shift value for getting the SYSRET CS and SS value. */ #define MSR_K6_STAR_SYSRET_CS_SS_SHIFT 48 /** Shift value for getting the SYSCALL CS and SS value. */ #define MSR_K6_STAR_SYSCALL_CS_SS_SHIFT 32 /** Selector mask for use after shifting. */ -#define MSR_K6_STAR_SEL_MASK 0xffff +#define MSR_K6_STAR_SEL_MASK UINT32_C(0xffff) /** The mask which give the SYSCALL EIP. */ -#define MSR_K6_STAR_SYSCALL_EIP_MASK 0xffffffff +#define MSR_K6_STAR_SYSCALL_EIP_MASK UINT32_C(0xffffffff) /** K6 WHCR - Write Handling Control Register. */ -#define MSR_K6_WHCR 0xc0000082 +#define MSR_K6_WHCR UINT32_C(0xc0000082) /** K6 UWCCR - UC/WC Cacheability Control Register. */ -#define MSR_K6_UWCCR 0xc0000085 +#define MSR_K6_UWCCR UINT32_C(0xc0000085) /** K6 PSOR - Processor State Observability Register. */ -#define MSR_K6_PSOR 0xc0000087 +#define MSR_K6_PSOR UINT32_C(0xc0000087) /** K6 PFIR - Page Flush/Invalidate Register. */ -#define MSR_K6_PFIR 0xc0000088 +#define MSR_K6_PFIR UINT32_C(0xc0000088) /** Performance counter MSRs. (AMD only) */ -#define MSR_K7_EVNTSEL0 0xc0010000 -#define MSR_K7_EVNTSEL1 0xc0010001 -#define MSR_K7_EVNTSEL2 0xc0010002 -#define MSR_K7_EVNTSEL3 0xc0010003 -#define MSR_K7_PERFCTR0 0xc0010004 -#define MSR_K7_PERFCTR1 0xc0010005 -#define MSR_K7_PERFCTR2 0xc0010006 -#define MSR_K7_PERFCTR3 0xc0010007 +#define MSR_K7_EVNTSEL0 UINT32_C(0xc0010000) +#define MSR_K7_EVNTSEL1 UINT32_C(0xc0010001) +#define MSR_K7_EVNTSEL2 UINT32_C(0xc0010002) +#define MSR_K7_EVNTSEL3 UINT32_C(0xc0010003) +#define MSR_K7_PERFCTR0 UINT32_C(0xc0010004) +#define MSR_K7_PERFCTR1 UINT32_C(0xc0010005) +#define MSR_K7_PERFCTR2 UINT32_C(0xc0010006) +#define MSR_K7_PERFCTR3 UINT32_C(0xc0010007) /** K8 LSTAR - Long mode SYSCALL target (RIP). */ -#define MSR_K8_LSTAR 0xc0000082 +#define MSR_K8_LSTAR UINT32_C(0xc0000082) /** K8 CSTAR - Compatibility mode SYSCALL target (RIP). */ -#define MSR_K8_CSTAR 0xc0000083 +#define MSR_K8_CSTAR UINT32_C(0xc0000083) /** K8 SF_MASK - SYSCALL flag mask. (aka SFMASK) */ -#define MSR_K8_SF_MASK 0xc0000084 +#define MSR_K8_SF_MASK UINT32_C(0xc0000084) /** K8 FS.base - The 64-bit base FS register. */ -#define MSR_K8_FS_BASE 0xc0000100 +#define MSR_K8_FS_BASE UINT32_C(0xc0000100) /** K8 GS.base - The 64-bit base GS register. */ -#define MSR_K8_GS_BASE 0xc0000101 +#define MSR_K8_GS_BASE UINT32_C(0xc0000101) /** K8 KernelGSbase - Used with SWAPGS. */ -#define MSR_K8_KERNEL_GS_BASE 0xc0000102 +#define MSR_K8_KERNEL_GS_BASE UINT32_C(0xc0000102) /** K8 TSC_AUX - Used with RDTSCP. */ -#define MSR_K8_TSC_AUX 0xc0000103 -#define MSR_K8_SYSCFG 0xc0010010 -#define MSR_K8_HWCR 0xc0010015 -#define MSR_K8_IORRBASE0 0xc0010016 -#define MSR_K8_IORRMASK0 0xc0010017 -#define MSR_K8_IORRBASE1 0xc0010018 -#define MSR_K8_IORRMASK1 0xc0010019 -#define MSR_K8_TOP_MEM1 0xc001001a -#define MSR_K8_TOP_MEM2 0xc001001d -#define MSR_K8_VM_CR 0xc0010114 +#define MSR_K8_TSC_AUX UINT32_C(0xc0000103) +#define MSR_K8_SYSCFG UINT32_C(0xc0010010) +#define MSR_K8_HWCR UINT32_C(0xc0010015) +#define MSR_K8_IORRBASE0 UINT32_C(0xc0010016) +#define MSR_K8_IORRMASK0 UINT32_C(0xc0010017) +#define MSR_K8_IORRBASE1 UINT32_C(0xc0010018) +#define MSR_K8_IORRMASK1 UINT32_C(0xc0010019) +#define MSR_K8_TOP_MEM1 UINT32_C(0xc001001a) +#define MSR_K8_TOP_MEM2 UINT32_C(0xc001001d) +/** North bridge config? See BIOS & Kernel dev guides for + * details. */ +#define MSR_K8_NB_CFG UINT32_C(0xc001001f) + +/** Hypertransport interrupt pending register. + * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors" */ +#define MSR_K8_INT_PENDING UINT32_C(0xc0010055) +#define MSR_K8_VM_CR UINT32_C(0xc0010114) #define MSR_K8_VM_CR_SVM_DISABLE RT_BIT(4) -#define MSR_K8_IGNNE 0xc0010115 -#define MSR_K8_SMM_CTL 0xc0010116 +#define MSR_K8_IGNNE UINT32_C(0xc0010115) +#define MSR_K8_SMM_CTL UINT32_C(0xc0010116) /** SVM - VM_HSAVE_PA - Physical address for saving and restoring - * host state during world switch. - */ -#define MSR_K8_VM_HSAVE_PA 0xc0010117 + * host state during world switch. */ +#define MSR_K8_VM_HSAVE_PA UINT32_C(0xc0010117) /** @} */ @@ -1173,6 +1302,10 @@ typedef X86PGPAEUINT const *PCX86PGPAEUINT; /** The 4MB page base mask for virtual addresses - 32bit version. */ #define X86_PAGE_4M_BASE_MASK_32 0xffc00000U +/** + * Check if the given address is canonical. + */ +#define X86_IS_CANONICAL(a_u64Addr) ((uint64_t)(a_u64Addr) + UINT64_C(0x800000000000) < UINT64_C(0x1000000000000)) /** @name Page Table Entry @@ -2219,6 +2352,55 @@ typedef const X86FXSTATE *PCX86FXSTATE; #define X86_FCW_ZERO_MASK UINT16_C(0xf080) /** @} */ +/** @name SSE MXCSR + * @{ */ +/** Exception Flag: Invalid operation. */ +#define X86_MSXCR_IE RT_BIT(0) +/** Exception Flag: Denormalized operand. */ +#define X86_MSXCR_DE RT_BIT(1) +/** Exception Flag: Zero divide. */ +#define X86_MSXCR_ZE RT_BIT(2) +/** Exception Flag: Overflow. */ +#define X86_MSXCR_OE RT_BIT(3) +/** Exception Flag: Underflow. */ +#define X86_MSXCR_UE RT_BIT(4) +/** Exception Flag: Precision. */ +#define X86_MSXCR_PE RT_BIT(5) + +/** Denormals are zero. */ +#define X86_MSXCR_DAZ RT_BIT(6) + +/** Exception Mask: Invalid operation. */ +#define X86_MSXCR_IM RT_BIT(7) +/** Exception Mask: Denormalized operand. */ +#define X86_MSXCR_DM RT_BIT(8) +/** Exception Mask: Zero divide. */ +#define X86_MSXCR_ZM RT_BIT(9) +/** Exception Mask: Overflow. */ +#define X86_MSXCR_OM RT_BIT(10) +/** Exception Mask: Underflow. */ +#define X86_MSXCR_UM RT_BIT(11) +/** Exception Mask: Precision. */ +#define X86_MSXCR_PM RT_BIT(12) + +/** Rounding control mask. */ +#define X86_MSXCR_RC_MASK UINT16_C(0x6000) +/** Rounding control: To nearest. */ +#define X86_MSXCR_RC_NEAREST UINT16_C(0x0000) +/** Rounding control: Down. */ +#define X86_MSXCR_RC_DOWN UINT16_C(0x2000) +/** Rounding control: Up. */ +#define X86_MSXCR_RC_UP UINT16_C(0x4000) +/** Rounding control: Towards zero. */ +#define X86_MSXCR_RC_ZERO UINT16_C(0x6000) + +/** Flush-to-zero for masked underflow. */ +#define X86_MSXCR_FZ RT_BIT(15) + +/** Misaligned Exception Mask. */ +#define X86_MSXCR_MM RT_BIT(16) +/** @} */ + /** @name Selector Descriptor * @{ @@ -2226,7 +2408,7 @@ typedef const X86FXSTATE *PCX86FXSTATE; #ifndef VBOX_FOR_DTRACE_LIB /** - * Descriptor attributes. + * Descriptor attributes (as seen by VT-x). */ typedef struct X86DESCATTRBITS { @@ -2250,9 +2432,26 @@ typedef struct X86DESCATTRBITS /** 0f - Granularity of the limit. If set 4KB granularity is used, if * clear byte. */ unsigned u1Granularity : 1; + /** 10 - "Unusable" selector, special Intel (VT-x only?) bit. */ + unsigned u1Unusable : 1; } X86DESCATTRBITS; #endif /* !VBOX_FOR_DTRACE_LIB */ +/** @name X86DESCATTR masks + * @{ */ +#define X86DESCATTR_TYPE UINT32_C(0x0000000f) +#define X86DESCATTR_DT UINT32_C(0x00000010) +#define X86DESCATTR_DPL UINT32_C(0x00000060) +#define X86DESCATTR_DPL_SHIFT 5 /**< Shift count for the DPL value. */ +#define X86DESCATTR_P UINT32_C(0x00000080) +#define X86DESCATTR_LIMIT_HIGH UINT32_C(0x00000f00) +#define X86DESCATTR_AVL UINT32_C(0x00001000) +#define X86DESCATTR_L UINT32_C(0x00002000) +#define X86DESCATTR_D UINT32_C(0x00004000) +#define X86DESCATTR_G UINT32_C(0x00008000) +#define X86DESCATTR_UNUSABLE UINT32_C(0x00010000) +/** @} */ + #pragma pack(1) typedef union X86DESCATTR { @@ -2277,34 +2476,34 @@ typedef const X86DESCATTR *PCX86DESCATTR; #pragma pack(1) typedef struct X86DESCGENERIC { - /** Limit - Low word. */ + /** 00 - Limit - Low word. */ unsigned u16LimitLow : 16; - /** Base address - lowe word. + /** 10 - Base address - lowe word. * Don't try set this to 24 because MSC is doing stupid things then. */ unsigned u16BaseLow : 16; - /** Base address - first 8 bits of high word. */ + /** 20 - Base address - first 8 bits of high word. */ unsigned u8BaseHigh1 : 8; - /** Segment Type. */ + /** 28 - Segment Type. */ unsigned u4Type : 4; - /** Descriptor Type. System(=0) or code/data selector */ + /** 2c - Descriptor Type. System(=0) or code/data selector */ unsigned u1DescType : 1; - /** Descriptor Privelege level. */ + /** 2d - Descriptor Privelege level. */ unsigned u2Dpl : 2; - /** Flags selector present(=1) or not. */ + /** 2f - Flags selector present(=1) or not. */ unsigned u1Present : 1; - /** Segment limit 16-19. */ + /** 30 - Segment limit 16-19. */ unsigned u4LimitHigh : 4; - /** Available for system software. */ + /** 34 - Available for system software. */ unsigned u1Available : 1; - /** 32 bits mode: Reserved - 0, long mode: Long Attribute Bit. */ + /** 35 - 32 bits mode: Reserved - 0, long mode: Long Attribute Bit. */ unsigned u1Long : 1; - /** This flags meaning depends on the segment type. Try make sense out + /** 36 - This flags meaning depends on the segment type. Try make sense out * of the intel manual yourself. */ unsigned u1DefBig : 1; - /** Granularity of the limit. If set 4KB granularity is used, if + /** 37 - Granularity of the limit. If set 4KB granularity is used, if * clear byte. */ unsigned u1Granularity : 1; - /** Base address - highest 8 bits. */ + /** 38 - Base address - highest 8 bits. */ unsigned u8BaseHigh2 : 8; } X86DESCGENERIC; #pragma pack() @@ -3041,7 +3240,7 @@ typedef enum X86XCPT X86_XCPT_GP = 0x0d, /** \#PF - Page fault. */ X86_XCPT_PF = 0x0e, - /* 0x0f is reserved. */ + /* 0x0f is reserved (to avoid conflict with spurious interrupts in BIOS setup). */ /** \#MF - Math fault (FPU). */ X86_XCPT_MF = 0x10, /** \#AC - Alignment check. */ @@ -3049,12 +3248,18 @@ typedef enum X86XCPT /** \#MC - Machine check. */ X86_XCPT_MC = 0x12, /** \#XF - SIMD Floating-Pointer Exception. */ - X86_XCPT_XF = 0x13 + X86_XCPT_XF = 0x13, + /** \#VE - Virtualzation Exception. */ + X86_XCPT_VE = 0x14, + /** \#SX - Security Exception. */ + X86_XCPT_SX = 0x1f } X86XCPT; /** Pointer to a x86 exception code. */ typedef X86XCPT *PX86XCPT; /** Pointer to a const x86 exception code. */ typedef const X86XCPT *PCX86XCPT; +/** The maximum exception value. */ +#define X86_XCPT_MAX (X86_XCPT_SX) /** @name Trap Error Codes @@ -3088,6 +3293,19 @@ typedef const X86XCPT *PCX86XCPT; #define X86_TRAP_PF_ID RT_BIT(4) /** @} */ +#pragma pack(1) +/** + * 16-bit IDTR. + */ +typedef struct X86IDTR16 +{ + /** Offset. */ + uint16_t offSel; + /** Selector. */ + uint16_t uSel; +} X86IDTR16, *PX86IDTR16; +#pragma pack() + #pragma pack(1) /** * 32-bit IDTR/GDTR. @@ -3188,6 +3406,26 @@ AssertCompile((X86_SIB_SCALE_MASK >> X86_SIB_SCALE_SHIFT) == X86_SIB_SCALE_SMASK #define X86_SREG_COUNT 6 +/** @name X86_OP_XXX - Prefixes + * @{ */ +#define X86_OP_PRF_CS UINT8_C(0x2e) +#define X86_OP_PRF_SS UINT8_C(0x36) +#define X86_OP_PRF_DS UINT8_C(0x3e) +#define X86_OP_PRF_ES UINT8_C(0x26) +#define X86_OP_PRF_FS UINT8_C(0x64) +#define X86_OP_PRF_GS UINT8_C(0x65) +#define X86_OP_PRF_SIZE_OP UINT8_C(0x66) +#define X86_OP_PRF_SIZE_ADDR UINT8_C(0x67) +#define X86_OP_PRF_LOCK UINT8_C(0xf0) +#define X86_OP_PRF_REPZ UINT8_C(0xf2) +#define X86_OP_PRF_REPNZ UINT8_C(0xf3) +#define X86_OP_REX_B UINT8_C(0x41) +#define X86_OP_REX_X UINT8_C(0x42) +#define X86_OP_REX_R UINT8_C(0x44) +#define X86_OP_REX_W UINT8_C(0x48) +/** @} */ + + /** @} */ #endif diff --git a/include/iprt/x86.mac b/include/iprt/x86.mac index d9765261..bf10b660 100644 --- a/include/iprt/x86.mac +++ b/include/iprt/x86.mac @@ -12,15 +12,20 @@ %ifndef VBOX_FOR_DTRACE_LIB %endif %define X86_EFL_CF RT_BIT(0) +%define X86_EFL_CF_BIT 0 %define X86_EFL_1 RT_BIT(1) %define X86_EFL_PF RT_BIT(2) %define X86_EFL_AF RT_BIT(4) +%define X86_EFL_AF_BIT 4 %define X86_EFL_ZF RT_BIT(6) +%define X86_EFL_ZF_BIT 6 %define X86_EFL_SF RT_BIT(7) +%define X86_EFL_SF_BIT 7 %define X86_EFL_TF RT_BIT(8) %define X86_EFL_IF RT_BIT(9) %define X86_EFL_DF RT_BIT(10) %define X86_EFL_OF RT_BIT(11) +%define X86_EFL_OF_BIT 11 %define X86_EFL_IOPL (RT_BIT(12) | RT_BIT(13)) %define X86_EFL_NT RT_BIT(14) %define X86_EFL_RF RT_BIT(16) @@ -29,9 +34,13 @@ %define X86_EFL_VIF RT_BIT(19) %define X86_EFL_VIP RT_BIT(20) %define X86_EFL_ID RT_BIT(21) +%define X86_EFL_LIVE_MASK 0x003f7fd5 +%define X86_EFL_RA1_MASK RT_BIT_32(1) %define X86_EFL_IOPL_SHIFT 12 %define X86_EFL_GET_IOPL(efl) (((efl) >> X86_EFL_IOPL_SHIFT) & 3) -%define X86_EFL_POPF_BITS (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID) +%define X86_EFL_POPF_BITS ( X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF \ + | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID ) +%define X86_EFL_STATUS_BITS ( X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF ) %ifndef VBOX_FOR_DTRACE_LIB %else %endif @@ -74,6 +83,7 @@ %define X86_CPUID_FEATURE_ECX_XSAVE RT_BIT(26) %define X86_CPUID_FEATURE_ECX_OSXSAVE RT_BIT(27) %define X86_CPUID_FEATURE_ECX_AVX RT_BIT(28) +%define X86_CPUID_FEATURE_ECX_F16C RT_BIT(29) %define X86_CPUID_FEATURE_ECX_HVP RT_BIT(31) %define X86_CPUID_FEATURE_EDX_FPU RT_BIT(0) %define X86_CPUID_FEATURE_EDX_VME RT_BIT(1) @@ -203,10 +213,15 @@ %define X86_DR6_B1 RT_BIT(1) %define X86_DR6_B2 RT_BIT(2) %define X86_DR6_B3 RT_BIT(3) +%define X86_DR6_B_MASK 0x0000000f %define X86_DR6_BD RT_BIT(13) %define X86_DR6_BS RT_BIT(14) %define X86_DR6_BT RT_BIT(15) %define X86_DR6_INIT_VAL 0xFFFF0FF0 +%define X86_DR6_RA1_MASK 0xffff0ff0 +%define X86_DR6_RAZ_MASK RT_BIT_64(12) +%define X86_DR6_MBZ_MASK 0xffffffff00000000 +%define X86_DR6_B(iBp) RT_BIT_64(iBp) %define X86_DR7_L0 RT_BIT(0) %define X86_DR7_G0 RT_BIT(1) %define X86_DR7_L1 RT_BIT(2) @@ -217,6 +232,8 @@ %define X86_DR7_G3 RT_BIT(7) %define X86_DR7_LE RT_BIT(8) %define X86_DR7_GE RT_BIT(9) +%define X86_DR7_LE_ALL 0x0000000000000055 +%define X86_DR7_GE_ALL 0x00000000000000aa %define X86_DR7_GD RT_BIT(13) %define X86_DR7_RW0_MASK (3 << 16) %define X86_DR7_LEN0_MASK (3 << 18) @@ -226,30 +243,49 @@ %define X86_DR7_LEN2_MASK (3 << 26) %define X86_DR7_RW3_MASK (3 << 28) %define X86_DR7_LEN3_MASK (3 << 30) -%define X86_DR7_MB1_MASK (RT_BIT(10)) +%define X86_DR7_RA1_MASK (RT_BIT(10)) +%define X86_DR7_RAZ_MASK 0x0000d800 +%define X86_DR7_MBZ_MASK 0xffffffff00000000 %define X86_DR7_L(iBp) ( 1 << (iBp * 2) ) %define X86_DR7_G(iBp) ( 1 << (iBp * 2 + 1) ) +%define X86_DR7_L_G(iBp) ( 3 << (iBp * 2) ) %define X86_DR7_RW_EO 0 %define X86_DR7_RW_WO 1 %define X86_DR7_RW_IO 2 %define X86_DR7_RW_RW 3 %define X86_DR7_RW(iBp, fRw) ( (fRw) << ((iBp) * 4 + 16) ) +%define X86_DR7_GET_RW(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 16) ) & 3 ) +%define X86_DR7_RW_ALL_MASKS 0x33330000 +%define X86_DR7_ANY_RW_IO(uDR7) \ + ( ( 0x22220000 & (uDR7) ) %define X86_DR7_LEN_BYTE 0 %define X86_DR7_LEN_WORD 1 %define X86_DR7_LEN_QWORD 2 %define X86_DR7_LEN_DWORD 3 %define X86_DR7_LEN(iBp, cb) ( (cb) << ((iBp) * 4 + 18) ) -%define X86_DR7_GET_LEN(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 18) ) & 0x3) -%define X86_DR7_ENABLED_MASK (RT_BIT(0) | RT_BIT(1) | RT_BIT(2) | RT_BIT(3) | RT_BIT(4) | RT_BIT(5) | RT_BIT(6) | RT_BIT(7)) -%define X86_DR7_IO_ENABLED_MASK (X86_DR7_RW(0, X86_DR7_RW_IO) | X86_DR7_RW(1, X86_DR7_RW_IO) | X86_DR7_RW(2, X86_DR7_RW_IO) | X86_DR7_RW(3, X86_DR7_RW_IO)) +%define X86_DR7_GET_LEN(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 18) ) & 0x3 ) +%define X86_DR7_ENABLED_MASK 0x000000ff +%define X86_DR7_LEN_ALL_MASKS 0xcccc0000 +%define X86_DR7_RW_LEN_ALL_MASKS 0xffff0000 %define X86_DR7_INIT_VAL 0x400 +%define MSR_P5_MC_ADDR 0x00000000 +%define MSR_P5_MC_TYPE 0x00000001 %define MSR_IA32_TSC 0x10 +%define MSR_IA32_CESR 0x00000011 +%define MSR_IA32_CTR0 0x00000012 +%define MSR_IA32_CTR1 0x00000013 %define MSR_IA32_PLATFORM_ID 0x17 %ifndef MSR_IA32_APICBASE -%define MSR_IA32_APICBASE 0x1b + %define MSR_IA32_APICBASE 0x1b + %define MSR_IA32_APICBASE_EN RT_BIT_64(11) + %define MSR_IA32_APICBASE_EXTD RT_BIT_64(10) + %define MSR_IA32_APICBASE_BSP RT_BIT_64(8) + %define MSR_IA32_APICBASE_BASE_MIN 0x0000000ffffff000 %endif +%define MSR_CORE_THREAD_COUNT 0x35 %define MSR_IA32_FEATURE_CONTROL 0x3A %define MSR_IA32_FEATURE_CONTROL_LOCK RT_BIT(0) +%define MSR_IA32_FEATURE_CONTROL_SMX_VMXON RT_BIT(1) %define MSR_IA32_FEATURE_CONTROL_VMXON RT_BIT(2) %define MSR_IA32_BIOS_UPDT_TRIG 0x79 %define MSR_IA32_BIOS_SIGN_ID 0x8B @@ -259,34 +295,43 @@ %define MSR_IA32_PMC3 0xC4 %define MSR_IA32_PLATFORM_INFO 0xCE %define MSR_IA32_FSB_CLOCK_STS 0xCD +%define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2 +%define MSR_IA32_MPERF 0xE7 +%define MSR_IA32_APERF 0xE8 %define MSR_IA32_MTRR_CAP 0xFE +%define MSR_BBL_CR_CTL3 0x11e %ifndef MSR_IA32_SYSENTER_CS %define MSR_IA32_SYSENTER_CS 0x174 %define MSR_IA32_SYSENTER_ESP 0x175 %define MSR_IA32_SYSENTER_EIP 0x176 %endif -%define MSR_IA32_MCP_CAP 0x179 -%define MSR_IA32_MCP_STATUS 0x17A -%define MSR_IA32_MCP_CTRL 0x17B -%define MSR_IA32_DEBUGCTL 0x1D9 +%define MSR_IA32_MCG_CAP 0x179 +%define MSR_IA32_MCG_STATUS 0x17A +%define MSR_IA32_MCG_CTRL 0x17B %define MSR_IA32_CR_PAT 0x277 %define MSR_IA32_PERFEVTSEL0 0x186 %define MSR_IA32_PERFEVTSEL1 0x187 -%define MSR_IA32_FLEX_RATIO 0x194 +%define MSR_FLEX_RATIO 0x194 %define MSR_IA32_PERF_STATUS 0x198 %define MSR_IA32_PERF_CTL 0x199 %define MSR_IA32_THERM_STATUS 0x19c %define MSR_IA32_MISC_ENABLE 0x1A0 -%define MSR_IA32_MISC_ENABLE_FAST_STRINGS RT_BIT(0) -%define MSR_IA32_MISC_ENABLE_TCC RT_BIT(3) -%define MSR_IA32_MISC_ENABLE_PERF_MON RT_BIT(7) -%define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL RT_BIT(11) -%define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL RT_BIT(12) -%define MSR_IA32_MISC_ENABLE_SST_ENABLE RT_BIT(16) -%define MSR_IA32_MISC_ENABLE_MONITOR RT_BIT(18) -%define MSR_IA32_MISC_ENABLE_LIMIT_CPUID RT_BIT(22) -%define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE RT_BIT(23) -%define MSR_IA32_MISC_ENABLE_XD_DISABLE RT_BIT(34) +%define MSR_IA32_MISC_ENABLE_FAST_STRINGS RT_BIT_64(0) +%define MSR_IA32_MISC_ENABLE_TCC RT_BIT_64(3) +%define MSR_IA32_MISC_ENABLE_PERF_MON RT_BIT_64(7) +%define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL RT_BIT_64(11) +%define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL RT_BIT_64(12) +%define MSR_IA32_MISC_ENABLE_SST_ENABLE RT_BIT_64(16) +%define MSR_IA32_MISC_ENABLE_MONITOR RT_BIT_64(18) +%define MSR_IA32_MISC_ENABLE_LIMIT_CPUID RT_BIT_64(22) +%define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE RT_BIT_64(23) +%define MSR_IA32_MISC_ENABLE_XD_DISABLE RT_BIT_64(34) +%define MSR_IA32_DEBUGCTL 0x000001d9 +%define MSR_P4_LASTBRANCH_TOS 0x000001da +%define MSR_P4_LASTBRANCH_0 0x000001db +%define MSR_P4_LASTBRANCH_1 0x000001dc +%define MSR_P4_LASTBRANCH_2 0x000001dd +%define MSR_P4_LASTBRANCH_3 0x000001de %define IA32_MTRR_PHYSBASE0 0x200 %define IA32_MTRR_PHYSMASK0 0x201 %define IA32_MTRR_PHYSBASE1 0x202 @@ -332,11 +377,14 @@ %define MSR_IA32_VMX_CR4_FIXED0 0x488 %define MSR_IA32_VMX_CR4_FIXED1 0x489 %define MSR_IA32_VMX_VMCS_ENUM 0x48A +%define MSR_IA32_VMX_VMFUNC 0x491 %define MSR_IA32_VMX_PROCBASED_CTLS2 0x48B -%define MSR_IA32_VMX_EPT_CAPS 0x48C +%define MSR_IA32_VMX_EPT_VPID_CAP 0x48C %define MSR_IA32_DS_AREA 0x600 -%define MSR_IA32_APIC_START 0x800 -%define MSR_IA32_APIC_END 0x900 +%define MSR_RAPL_POWER_UNIT 0x606 +%define MSR_IA32_X2APIC_START 0x800 +%define MSR_IA32_X2APIC_TPR 0x808 +%define MSR_IA32_X2APIC_END 0xBFF %define MSR_K6_EFER 0xc0000080 %define MSR_K6_EFER_SCE RT_BIT(0) %define MSR_K6_EFER_LME RT_BIT(8) @@ -377,6 +425,8 @@ %define MSR_K8_IORRMASK1 0xc0010019 %define MSR_K8_TOP_MEM1 0xc001001a %define MSR_K8_TOP_MEM2 0xc001001d +%define MSR_K8_NB_CFG 0xc001001f +%define MSR_K8_INT_PENDING 0xc0010055 %define MSR_K8_VM_CR 0xc0010114 %define MSR_K8_VM_CR_SVM_DISABLE RT_BIT(4) %define MSR_K8_IGNNE 0xc0010115 @@ -402,6 +452,7 @@ %define X86_PAGE_4M_OFFSET_MASK 0x003fffff %define X86_PAGE_4M_BASE_MASK 0xffffffffffc00000 %define X86_PAGE_4M_BASE_MASK_32 0xffc00000 +%define X86_IS_CANONICAL(a_u64Addr) ((uint64_t)(a_u64Addr) + 0x800000000000 < UINT64_C(0x1000000000000)) %define X86_PTE_BIT_P 0 %define X86_PTE_BIT_RW 1 %define X86_PTE_BIT_US 2 @@ -543,8 +594,39 @@ %define X86_FCW_RC_UP 0x0800 %define X86_FCW_RC_ZERO 0x0c00 %define X86_FCW_ZERO_MASK 0xf080 +%define X86_MSXCR_IE RT_BIT(0) +%define X86_MSXCR_DE RT_BIT(1) +%define X86_MSXCR_ZE RT_BIT(2) +%define X86_MSXCR_OE RT_BIT(3) +%define X86_MSXCR_UE RT_BIT(4) +%define X86_MSXCR_PE RT_BIT(5) +%define X86_MSXCR_DAZ RT_BIT(6) +%define X86_MSXCR_IM RT_BIT(7) +%define X86_MSXCR_DM RT_BIT(8) +%define X86_MSXCR_ZM RT_BIT(9) +%define X86_MSXCR_OM RT_BIT(10) +%define X86_MSXCR_UM RT_BIT(11) +%define X86_MSXCR_PM RT_BIT(12) +%define X86_MSXCR_RC_MASK 0x6000 +%define X86_MSXCR_RC_NEAREST 0x0000 +%define X86_MSXCR_RC_DOWN 0x2000 +%define X86_MSXCR_RC_UP 0x4000 +%define X86_MSXCR_RC_ZERO 0x6000 +%define X86_MSXCR_FZ RT_BIT(15) +%define X86_MSXCR_MM RT_BIT(16) %ifndef VBOX_FOR_DTRACE_LIB %endif +%define X86DESCATTR_TYPE 0x0000000f +%define X86DESCATTR_DT 0x00000010 +%define X86DESCATTR_DPL 0x00000060 +%define X86DESCATTR_DPL_SHIFT 5 +%define X86DESCATTR_P 0x00000080 +%define X86DESCATTR_LIMIT_HIGH 0x00000f00 +%define X86DESCATTR_AVL 0x00001000 +%define X86DESCATTR_L 0x00002000 +%define X86DESCATTR_D 0x00004000 +%define X86DESCATTR_G 0x00008000 +%define X86DESCATTR_UNUSABLE 0x00010000 %ifndef VBOX_FOR_DTRACE_LIB %endif %ifndef VBOX_FOR_DTRACE_LIB @@ -645,6 +727,7 @@ %define X86_SEL_LDT 0x0004 %define X86_SEL_RPL 0x0003 %define X86_SEL_RPL_LDT 0x0007 +%define X86_XCPT_MAX (X86_XCPT_SX) %define X86_TRAP_ERR_EXTERNAL 1 %define X86_TRAP_ERR_IDT 2 %define X86_TRAP_ERR_TI 4 @@ -702,5 +785,20 @@ %define X86_SREG_FS 4 %define X86_SREG_GS 5 %define X86_SREG_COUNT 6 +%define X86_OP_PRF_CS 0x2e +%define X86_OP_PRF_SS 0x36 +%define X86_OP_PRF_DS 0x3e +%define X86_OP_PRF_ES 0x26 +%define X86_OP_PRF_FS 0x64 +%define X86_OP_PRF_GS 0x65 +%define X86_OP_PRF_SIZE_OP 0x66 +%define X86_OP_PRF_SIZE_ADDR 0x67 +%define X86_OP_PRF_LOCK 0xf0 +%define X86_OP_PRF_REPZ 0xf2 +%define X86_OP_PRF_REPNZ 0xf3 +%define X86_OP_REX_B 0x41 +%define X86_OP_REX_X 0x42 +%define X86_OP_REX_R 0x44 +%define X86_OP_REX_W 0x48 %endif %include "iprt/x86extra.mac" diff --git a/include/iprt/x86extra.mac b/include/iprt/x86extra.mac index f705984c..edae0dc6 100644 --- a/include/iprt/x86extra.mac +++ b/include/iprt/x86extra.mac @@ -4,7 +4,7 @@ ; ; -; Copyright (C) 2012 Oracle Corporation +; Copyright (C) 2012-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; @@ -28,12 +28,29 @@ %define ___iprt_x86extra_mac -%define X86_XCPT_UD 6 -%define X86_XCPT_GP 13 -%define X86_XCPT_PF 14 -%define X86_XCPT_MF 16 +%define X86_XCPT_DE 0x00 +%define X86_XCPT_DB 0x01 +%define X86_XCPT_NMI 0x02 +%define X86_XCPT_BP 0x03 +%define X86_XCPT_OF 0x04 +%define X86_XCPT_BR 0x05 +%define X86_XCPT_UD 0x06 +%define X86_XCPT_NM 0x07 +%define X86_XCPT_DF 0x08 +%define X86_XCPT_CO_SEG_OVERRUN 0x09 +%define X86_XCPT_TS 0x0a +%define X86_XCPT_NP 0x0b +%define X86_XCPT_SS 0x0c +%define X86_XCPT_GP 0x0d +%define X86_XCPT_PF 0x0e +%define X86_XCPT_MF 0x10 +%define X86_XCPT_AC 0x11 +%define X86_XCPT_MC 0x12 +%define X86_XCPT_XF 0x13 +%define X86_XCPT_VE 0x14 +%define X86_XCPT_SX 0x1f -%define PAGE_SIZE 0x1000 +%define PAGE_SIZE 0x1000 ;; @@ -99,5 +116,94 @@ struc X86FXSTATE endstruc +struc X86TSS16 + .selPrev resw 1 + .sp0 resw 1 + .ss0 resw 1 + .sp1 resw 1 + .ss1 resw 1 + .sp2 resw 1 + .ss2 resw 1 + .ip resw 1 + .flags resw 1 + .ax resw 1 + .cx resw 1 + .dx resw 1 + .bx resw 1 + .sp resw 1 + .bp resw 1 + .si resw 1 + .di resw 1 + .es resw 1 + .cs resw 1 + .ss resw 1 + .ds resw 1 + .selLdt resw 1 +endstruc +AssertCompileSize(X86TSS16, 44) + + +struc X86TSS32 + .selPrev resw 1 + .padding1 resw 1 + .esp0 resd 1 + .ss0 resw 1 + .padding_ss0 resw 1 + .esp1 resd 1 + .ss1 resw 1 + .padding_ss1 resw 1 + .esp2 resd 1 + .ss2 resw 1 + .padding_ss2 resw 1 + .cr3 resd 1 + .eip resd 1 + .eflags resd 1 + .eax resd 1 + .ecx resd 1 + .edx resd 1 + .ebx resd 1 + .esp resd 1 + .ebp resd 1 + .esi resd 1 + .edi resd 1 + .es resw 1 + .padding_es resw 1 + .cs resw 1 + .padding_cs resw 1 + .ss resw 1 + .padding_ss resw 1 + .ds resw 1 + .padding_ds resw 1 + .fs resw 1 + .padding_fs resw 1 + .gs resw 1 + .padding_gs resw 1 + .selLdt resw 1 + .padding_ldt resw 1 + .fDebugTrap resw 1 + .offIoBitmap resw 1 + .IntRedirBitmap resb 32 +endstruc + + +struc X86TSS64 + .u32Reserved resd 1 + .rsp0 resq 1 + .rsp1 resq 1 + .rsp2 resq 1 + .u32Reserved2 resd 2 + .ist1 resq 1 + .ist2 resq 1 + .ist3 resq 1 + .ist4 resq 1 + .ist5 resq 1 + .ist6 resq 1 + .ist7 resq 1 + .u16Reserved resw 5 + .offIoBitmap resw 1 + .IntRedirBitmap resb 32 +endstruc +AssertCompileSize(X86TSS64, 136) + %endif diff --git a/include/iprt/zip.h b/include/iprt/zip.h index f3bfd4bd..83ab92f7 100644 --- a/include/iprt/zip.h +++ b/include/iprt/zip.h @@ -3,7 +3,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; @@ -29,7 +29,6 @@ #include #include - RT_C_DECLS_BEGIN /** @defgroup grp_rt_zip RTZip - Compression @@ -221,13 +220,36 @@ RTDECL(int) RTZipBlockDecompress(RTZIPTYPE enmType, uint32_t fFlags, * * @returns IPRT status code. * - * @param hVfsIosIn The compressed input stream. The reference is - * not consumed, instead another one is retained. + * @param hVfsIosIn The compressed input stream (must be readable). + * The reference is not consumed, instead another + * one is retained. * @param fFlags Flags, MBZ. - * @param phVfsIosOut Where to return the handle to the gzip I/O - * stream. + * @param phVfsIosGunzip Where to return the handle to the gunzipped I/O + * stream (read). + */ +RTDECL(int) RTZipGzipDecompressIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSIOSTREAM phVfsIosGunzip); + +/** @name RTZipGzipDecompressIoStream flags. + * @{ */ +/** Allow the smaller ZLIB header as well as the regular GZIP header. */ +#define RTZIPGZIPDECOMP_F_ALLOW_ZLIB_HDR RT_BIT(0) +/** @} */ + + +/** + * Opens a gzip decompression I/O stream. + * + * @returns IPRT status code. + * + * @param hVfsIosDst The compressed output stream (must be writable). + * The reference is not consumed, instead another + * one is retained. + * @param fFlags Flags, MBZ. + * @param uLevel The gzip compression level, 1 thru 9. + * @param phVfsIosGzip Where to return the gzip input I/O stream handle + * (you write to this). */ -RTDECL(int) RTZipGzipDecompressIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSIOSTREAM phVfsIosOut); +RTDECL(int) RTZipGzipCompressIoStream(RTVFSIOSTREAM hVfsIosDst, uint32_t fFlags, uint8_t uLevel, PRTVFSIOSTREAM phVfsIosGzip); /** * Opens a TAR filesystem stream. @@ -255,6 +277,21 @@ RTDECL(int) RTZipTarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlag */ RTDECL(RTEXITCODE) RTZipTarCmd(unsigned cArgs, char **papszArgs); +/** + * Opens a XAR filesystem stream. + * + * This is used to extract, list or check a XAR archive. + * + * @returns IPRT status code. + * + * @param hVfsIosIn The compressed input stream. The reference is + * not consumed, instead another one is retained. + * @param fFlags Flags, MBZ. + * @param phVfsFss Where to return the handle to the XAR filesystem + * stream. + */ +RTDECL(int) RTZipXarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss); + /** @} */ RT_C_DECLS_END -- cgit v1.2.1