VirtualKD.cpp revision c05577cf78fa798f48bfad5d32a939f077f9760c
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualKD - Device stub/loader for fast Windows kernel-mode debugging.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Contributed by: Igor Shcherbakov
af062818b47340eef15700d2f0211576ba3506eevboxsync * Heavily modified after the contribution.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Copyright (C) 2010-2014 Oracle Corporation
af062818b47340eef15700d2f0211576ba3506eevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
af062818b47340eef15700d2f0211576ba3506eevboxsync * available from http://www.virtualbox.org. This file is free software;
af062818b47340eef15700d2f0211576ba3506eevboxsync * you can redistribute it and/or modify it under the terms of the GNU
af062818b47340eef15700d2f0211576ba3506eevboxsync * General Public License (GPL) as published by the Free Software
af062818b47340eef15700d2f0211576ba3506eevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
af062818b47340eef15700d2f0211576ba3506eevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync/*******************************************************************************
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync* Header Files *
b955672b950093ff7416d1269dd4d3b69983bd8fvboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Defined Constants And Macros *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Structures and Typedefs *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsynctypedef struct VKDREPLYHDR
af062818b47340eef15700d2f0211576ba3506eevboxsync virtual unsigned OnRequest(const char *pRequest, unsigned RequestSize, char **ppReply)=0;
af062818b47340eef15700d2f0211576ba3506eevboxsync virtual unsigned GetRPCCommandHeaderSize()=0;
af062818b47340eef15700d2f0211576ba3506eevboxsync virtual ~IKDClient() {}
af062818b47340eef15700d2f0211576ba3506eevboxsynctypedef IKDClient *(*PFNCreateVBoxKDClientEx)(unsigned version);
af062818b47340eef15700d2f0211576ba3506eevboxsynctypedef struct VIRTUALKD
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Internal Functions *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic DECLCALLBACK(int) vkdPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
af062818b47340eef15700d2f0211576ba3506eevboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
af062818b47340eef15700d2f0211576ba3506eevboxsync *pu32 = RT_MAKE_U32_FROM_U8('V', 'B', 'O', 'X'); /* 'XOBV', checked in VMWRPC.H */
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic DECLCALLBACK(int) vkdPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
af062818b47340eef15700d2f0211576ba3506eevboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
589fd26cedb2b4ebbed14f2964cad03cc8ebbca2vboxsync int rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)u32, &RequestHeader, sizeof(RequestHeader));
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)(u32 + sizeof(RequestHeader)), pThis->abCmdBody, RequestHeader.cbData);
af062818b47340eef15700d2f0211576ba3506eevboxsync cbReply = pThis->pKDClient->OnRequest(pThis->abCmdBody + pThis->cbRPCCommandHeaderSize,
af062818b47340eef15700d2f0211576ba3506eevboxsync RequestHeader.cbData - pThis->cbRPCCommandHeaderSize,
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)u32, &ReplyHeader, sizeof(ReplyHeader));
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)(u32 + sizeof(ReplyHeader)), pReply, cbReply);
af062818b47340eef15700d2f0211576ba3506eevboxsync * @interface_method_impl{PDMDEVREG,pfnConstruct}
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic DECLCALLBACK(int) vkdConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
af062818b47340eef15700d2f0211576ba3506eevboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
af062818b47340eef15700d2f0211576ba3506eevboxsync /* This device is a bit unusual, after this point it will not fail to be
af062818b47340eef15700d2f0211576ba3506eevboxsync * constructed, but there will be a warning and it will not work. */
af062818b47340eef15700d2f0211576ba3506eevboxsync CFGMR3QueryString(pCfg, "Path", szPath, sizeof(szPath));
af062818b47340eef15700d2f0211576ba3506eevboxsync "kdclient64.dll"
af062818b47340eef15700d2f0211576ba3506eevboxsync "kdclient.dll"
af062818b47340eef15700d2f0211576ba3506eevboxsync PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_LOAD",
af062818b47340eef15700d2f0211576ba3506eevboxsync N_("Failed to load VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = RTLdrGetSymbol(pThis->hLib, "CreateVBoxKDClientEx", (void **)&pfnInit);
af062818b47340eef15700d2f0211576ba3506eevboxsync PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_SYMBOL",
af062818b47340eef15700d2f0211576ba3506eevboxsync N_("Failed to find entry point for VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
af062818b47340eef15700d2f0211576ba3506eevboxsync pThis->pKDClient = pfnInit(IKDClient_InterfaceVersion);
af062818b47340eef15700d2f0211576ba3506eevboxsync PDMDevHlpVMSetRuntimeError(pDevIns, 0 /* fFlags */, "VirtualKD_INIT",
af062818b47340eef15700d2f0211576ba3506eevboxsync N_("Failed to initialize VirtualKD library '%s'. Fast kernel-mode debugging will not work"), szPath);
af062818b47340eef15700d2f0211576ba3506eevboxsync pThis->cbRPCCommandHeaderSize = pThis->pKDClient->GetRPCCommandHeaderSize();
af062818b47340eef15700d2f0211576ba3506eevboxsync PDMDevHlpIOPortRegister(pDevIns, 0x5658, 2, NULL, vkdPortWrite, vkdPortRead, NULL, NULL, "VirtualKD");
af062818b47340eef15700d2f0211576ba3506eevboxsync * @interface_method_impl{PDMDEVREG,pfnDestruct}
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic DECLCALLBACK(int) vkdDestruct(PPDMDEVINS pDevIns)
af062818b47340eef15700d2f0211576ba3506eevboxsync VIRTUALKD *pThis = PDMINS_2_DATA(pDevIns, VIRTUALKD *);
af062818b47340eef15700d2f0211576ba3506eevboxsync * The device registration structure.
af062818b47340eef15700d2f0211576ba3506eevboxsync /* u32Version */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* szName */
af062818b47340eef15700d2f0211576ba3506eevboxsync "VirtualKD",
af062818b47340eef15700d2f0211576ba3506eevboxsync /* szRCMod */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* szR0Mod */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pszDescription */
af062818b47340eef15700d2f0211576ba3506eevboxsync "Provides fast debugging interface when debugging Windows kernel",
af062818b47340eef15700d2f0211576ba3506eevboxsync /* fFlags */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* fClass */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* cMaxInstances */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* cbInstance */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnConstruct */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnDestruct */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnRelocate */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnIOCtl */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnPowerOn */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnReset */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnSuspend */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnResume */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnAttach */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnDetach */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnQueryInterface */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnInitComplete */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnPowerOff */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* pfnSoftReset */
af062818b47340eef15700d2f0211576ba3506eevboxsync /* u32VersionEnd */