DBGPlugInLinux.cpp revision 43747b1f0bc8302a238fb35e55857a5e9aa1933d
/* $Id$ */
/** @file
* DBGPlugInLinux - Debugger and Guest OS Digger Plugin For Linux.
*/
/*
* 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;
* 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.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "DBGPlugIns.h"
#include "DBGPlugInCommonELF.h"
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/** @name InternalLinux structures
* @{ */
/** @} */
/**
* Linux guest OS digger instance data.
*/
typedef struct DBGDIGGERLINUX
{
/** Whether the information is valid or not.
* (For fending off illegal interface method calls.) */
bool fValid;
/** The address of the linux banner.
* This is set during probing. */
/** Kernel base address.
* This is set during probing. */
/** Pointer to the linux guest OS digger instance data. */
typedef DBGDIGGERLINUX *PDBGDIGGERLINUX;
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/** Validates a 32-bit linux kernel address */
/** The max kernel size. */
#define LNX_MAX_KERNEL_SIZE 0x0f000000
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** Table of common linux kernel addresses. */
static uint64_t g_au64LnxKernelAddresses[] =
{
UINT64_C(0xc0100000),
UINT64_C(0x90100000),
UINT64_C(0xffffffff80200000)
};
/**
* @copydoc DBGFOSREG::pfnQueryInterface
*/
static DECLCALLBACK(void *) dbgDiggerLinuxQueryInterface(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf)
{
return NULL;
}
/**
* @copydoc DBGFOSREG::pfnQueryVersion
*/
static DECLCALLBACK(int) dbgDiggerLinuxQueryVersion(PVM pVM, void *pvData, char *pszVersion, size_t cchVersion)
{
/*
* It's all in the linux banner.
*/
if (RT_SUCCESS(rc))
{
while ( pszEnd > pszVersion
pszEnd--;
*pszEnd = '\0';
}
else
return rc;
}
/**
* @copydoc DBGFOSREG::pfnTerm
*/
{
}
/**
* @copydoc DBGFOSREG::pfnRefresh
*/
{
/*
* For now we'll flush and reload everything.
*/
}
/**
* @copydoc DBGFOSREG::pfnInit
*/
{
#if 0 /* later */
int rc;
/*
* Algorithm to find the ksymtab:
* 1. Find a known export string in kstrtab ("init_task", "enable_hlt" or something).
* 2. Search for the address its at, this should give you the corresponding ksymtab entry.
* 3. Search backwards assuming that kstrtab is corresponding to ksymtab.
*/
#endif
return VINF_SUCCESS;
}
/**
* @copydoc DBGFOSREG::pfnProbe
*/
{
/*
* Look for "Linux version " at the start of the rodata segment.
* Hope that this comes before any message buffer or other similar string.
* .
* Note! Only Linux version 2.x.y, where x in {0..6}. .
*/
for (unsigned i = 0; i < RT_ELEMENTS(g_au64LnxKernelAddresses); i++)
{
if (RT_SUCCESS(rc))
{
char szTmp[128];
if ( RT_SUCCESS(rc)
&& *pszY >= '0'
&& *pszY <= '6')
{
return true;
}
}
}
return false;
}
/**
* @copydoc DBGFOSREG::pfnDestruct
*/
{
}
/**
* @copydoc DBGFOSREG::pfnConstruct
*/
{
return VINF_SUCCESS;
}
const DBGFOSREG g_DBGDiggerLinux =
{
/* .u32Magic = */ DBGFOSREG_MAGIC,
/* .fFlags = */ 0,
/* .cbData = */ sizeof(DBGDIGGERLINUX),
/* .szName = */ "Linux",
/* .pfnConstruct = */ dbgDiggerLinuxConstruct,
/* .pfnDestruct = */ dbgDiggerLinuxDestruct,
/* .pfnProbe = */ dbgDiggerLinuxProbe,
/* .pfnInit = */ dbgDiggerLinuxInit,
/* .pfnRefresh = */ dbgDiggerLinuxRefresh,
/* .pfnTerm = */ dbgDiggerLinuxTerm,
/* .pfnQueryVersion = */ dbgDiggerLinuxQueryVersion,
/* .pfnQueryInterface = */ dbgDiggerLinuxQueryInterface,
/* .u32EndMagic = */ DBGFOSREG_MAGIC
};