VirtualBox

Changeset 77874 in vbox


Ignore:
Timestamp:
Mar 26, 2019 1:37:19 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129567
Message:

DBGPlugInLinux: Started looking for kernel modules. Works to some extent for 2.6.24.

Location:
trunk/src/VBox/Debugger
Files:
3 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGPlugInLinux.cpp

    r77775 r77874  
    992992    if (offDst <= cbBuf)
    993993        return VINF_SUCCESS;
    994     else
    995         return VERR_BUFFER_OVERFLOW;
     994    return VERR_BUFFER_OVERFLOW;
    996995}
    997996
     
    11491148static DECLCALLBACK(void)  dbgDiggerLinuxTerm(PUVM pUVM, void *pvData)
    11501149{
    1151     RT_NOREF1(pUVM);
    11521150    PDBGDIGGERLINUX pThis = (PDBGDIGGERLINUX)pvData;
    11531151    Assert(pThis->fValid);
    11541152
     1153    /*
     1154     * Destroy configuration database.
     1155     */
    11551156    dbgDiggerLinuxCfgDbDestroy(pThis);
     1157
     1158    /*
     1159     * Unlink and release our modules.
     1160     */
     1161    RTDBGAS hDbgAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
     1162    if (hDbgAs != NIL_RTDBGAS)
     1163    {
     1164        uint32_t iMod = RTDbgAsModuleCount(hDbgAs);
     1165        while (iMod-- > 0)
     1166        {
     1167            RTDBGMOD hMod = RTDbgAsModuleByIndex(hDbgAs, iMod);
     1168            if (hMod != NIL_RTDBGMOD)
     1169            {
     1170                if (RTDbgModGetTag(hMod) == DIG_LNX_MOD_TAG)
     1171                {
     1172                    int rc = RTDbgAsModuleUnlink(hDbgAs, hMod);
     1173                    AssertRC(rc);
     1174                }
     1175                RTDbgModRelease(hMod);
     1176            }
     1177        }
     1178        RTDbgAsRelease(hDbgAs);
     1179    }
     1180
    11561181    pThis->fValid = false;
    11571182}
     
    19051930static int dbgDiggerLinuxLoadKernelSymbols(PUVM pUVM, PDBGDIGGERLINUX pThis)
    19061931{
     1932    /*
     1933     * First the kernel itself.
     1934     */
    19071935    if (pThis->fRelKrnlAddr)
    19081936        return dbgDiggerLinuxLoadKernelSymbolsRelative(pUVM, pThis);
    1909     else
    1910         return dbgDiggerLinuxLoadKernelSymbolsAbsolute(pUVM, pThis);
    1911 }
     1937    return dbgDiggerLinuxLoadKernelSymbolsAbsolute(pUVM, pThis);
     1938}
     1939
     1940
     1941/*
     1942 * The module structure changed it was easier to produce different code for
     1943 * each version of the structure.  The C preprocessor rules!
     1944 */
     1945#define LNX_TEMPLATE_HEADER "DBGPlugInLinuxModuleCodeTmpl.cpp.h"
     1946
     1947#define LNX_BIT_SUFFIX      _amd64
     1948#define LNX_PTR_T           uint64_t
     1949#define LNX_64BIT           1
     1950#include "DBGPlugInLinuxModuleVerTmpl.cpp.h"
     1951
     1952#define LNX_BIT_SUFFIX      _x86
     1953#define LNX_PTR_T           uint32_t
     1954#define LNX_64BIT           0
     1955#include "DBGPlugInLinuxModuleVerTmpl.cpp.h"
     1956
     1957#undef  LNX_TEMPLATE_HEADER
     1958
     1959static const struct
     1960{
     1961    uint32_t    uVersion;
     1962    bool        f64Bit;
     1963    uint64_t  (*pfnProcessModule)(PDBGDIGGERLINUX pThis, PUVM pUVM, PDBGFADDRESS pAddrModule);
     1964} g_aModVersions[] =
     1965{
     1966#define LNX_TEMPLATE_HEADER "DBGPlugInLinuxModuleTableEntryTmpl.cpp.h"
     1967
     1968#define LNX_BIT_SUFFIX      _amd64
     1969#define LNX_64BIT           1
     1970#include "DBGPlugInLinuxModuleVerTmpl.cpp.h"
     1971
     1972#define LNX_BIT_SUFFIX      _x86
     1973#define LNX_64BIT           0
     1974#include "DBGPlugInLinuxModuleVerTmpl.cpp.h"
     1975
     1976#undef  LNX_TEMPLATE_HEADER
     1977};
     1978
     1979
     1980/**
     1981 * Tries to find and process the module list.
     1982 *
     1983 * @returns VBox status code.
     1984 * @param   pThis               The Linux digger data.
     1985 * @param   pUVM                The user mode VM handle.
     1986 */
     1987static int dbgDiggerLinuxLoadModules(PDBGDIGGERLINUX pThis, PUVM pUVM)
     1988{
     1989    /*
     1990     * Locate the list head.
     1991     */
     1992    RTDBGAS     hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
     1993    RTDBGSYMBOL SymInfo;
     1994    int rc = RTDbgAsSymbolByName(hAs, "vmlinux!modules", &SymInfo, NULL);
     1995    RTDbgAsRelease(hAs);
     1996    if (RT_FAILURE(rc))
     1997        return VERR_NOT_FOUND;
     1998
     1999    if (RT_FAILURE(rc))
     2000    {
     2001        LogRel(("dbgDiggerLinuxLoadModules: Failed to locate the module list (%Rrc).\n", rc));
     2002        return VERR_NOT_FOUND;
     2003    }
     2004
     2005    /*
     2006     * Read the list anchor.
     2007     */
     2008    union
     2009    {
     2010        uint32_t volatile u32Pair[2];
     2011        uint64_t u64Pair[2];
     2012    } uListAnchor;
     2013    DBGFADDRESS Addr;
     2014    rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, SymInfo.Value),
     2015                       &uListAnchor, pThis->f64Bit ? sizeof(uListAnchor.u64Pair) : sizeof(uListAnchor.u32Pair));
     2016    if (RT_FAILURE(rc))
     2017    {
     2018        LogRel(("dbgDiggerLinuxLoadModules: Error reading list anchor at %RX64: %Rrc\n", SymInfo.Value, rc));
     2019        return VERR_NOT_FOUND;
     2020    }
     2021    if (!pThis->f64Bit)
     2022    {
     2023        uListAnchor.u64Pair[1] = uListAnchor.u32Pair[1];
     2024        ASMCompilerBarrier();
     2025        uListAnchor.u64Pair[0] = uListAnchor.u32Pair[0];
     2026    }
     2027
     2028    /*
     2029     * Get a numerical version number.
     2030     */
     2031    char szVersion[256] = "Linux version 4.19.0";
     2032    bool fValid = pThis->fValid;
     2033    pThis->fValid = true;
     2034    dbgDiggerLinuxQueryVersion(pUVM, pThis, szVersion, sizeof(szVersion));
     2035    pThis->fValid = fValid;
     2036
     2037    const char *pszVersion = szVersion;
     2038    while (*pszVersion && !RT_C_IS_DIGIT(*pszVersion))
     2039        pszVersion++;
     2040
     2041    size_t   offVersion = 0;
     2042    uint32_t uMajor = 0;
     2043    while (pszVersion[offVersion] && RT_C_IS_DIGIT(pszVersion[offVersion]))
     2044        uMajor = uMajor * 10 + pszVersion[offVersion++] - '0';
     2045
     2046    if (pszVersion[offVersion] == '.')
     2047        offVersion++;
     2048
     2049    uint32_t uMinor = 0;
     2050    while (pszVersion[offVersion] && RT_C_IS_DIGIT(pszVersion[offVersion]))
     2051        uMinor = uMinor * 10 + pszVersion[offVersion++] - '0';
     2052
     2053    if (pszVersion[offVersion] == '.')
     2054        offVersion++;
     2055
     2056    uint32_t uBuild = 0;
     2057    while (pszVersion[offVersion] && RT_C_IS_DIGIT(pszVersion[offVersion]))
     2058        uBuild = uBuild * 10 + pszVersion[offVersion++] - '0';
     2059
     2060    uint32_t const uGuestVer = LNX_MK_VER(uMajor, uMinor, uBuild);
     2061    if (uGuestVer == 0)
     2062    {
     2063        LogRel(("dbgDiggerLinuxLoadModules: Failed to parse version string: %s\n", pszVersion));
     2064        return VERR_NOT_FOUND;
     2065    }
     2066
     2067    /*
     2068     * Find the g_aModVersion entry that fits the best.
     2069     * ASSUMES strict descending order by bitcount and version.
     2070     */
     2071    Assert(g_aModVersions[0].f64Bit == true);
     2072    unsigned i = 0;
     2073    if (!pThis->f64Bit)
     2074        while (i < RT_ELEMENTS(g_aModVersions) && g_aModVersions[i].f64Bit)
     2075            i++;
     2076    while (   i < RT_ELEMENTS(g_aModVersions)
     2077           && g_aModVersions[i].f64Bit == pThis->f64Bit
     2078           && uGuestVer < g_aModVersions[i].uVersion)
     2079        i++;
     2080    if (i >= RT_ELEMENTS(g_aModVersions))
     2081    {
     2082        LogRel(("dbgDiggerLinuxLoadModules: Failed to find anything matching version: %u.%u.%u (%s)\n",
     2083                uMajor, uMinor, uBuild, pszVersion));
     2084        return VERR_NOT_FOUND;
     2085    }
     2086
     2087    /*
     2088     * Walk the list.
     2089     */
     2090    uint64_t uModAddr = uListAnchor.u64Pair[0];
     2091    for (size_t iModule = 0; iModule < 4096 && uModAddr != SymInfo.Value && uModAddr != 0; iModule++)
     2092        uModAddr = g_aModVersions[i].pfnProcessModule(pThis, pUVM, DBGFR3AddrFromFlat(pUVM, &Addr, uModAddr));
     2093
     2094    return VINF_SUCCESS;
     2095}
     2096
    19122097
    19132098/**
     
    20172202                    rc = dbgDiggerLinuxLoadKernelSymbols(pUVM, pThis);
    20182203                if (RT_SUCCESS(rc))
     2204                {
     2205                    rc = dbgDiggerLinuxLoadModules(pThis, pUVM);
    20192206                    break;
     2207                }
    20202208            }
    20212209        }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette