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