VirtualBox

Changeset 49075 in vbox for trunk


Ignore:
Timestamp:
Oct 14, 2013 1:59:59 AM (11 years ago)
Author:
vboxsync
Message:

DBGPlugInDarwin.cpp: Kind of works, with latest kldr and a symbol cache (by uuid lookup is the only way).

File:
1 edited

Legend:

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

    r49061 r49075  
    3838 * @{ */
    3939
     40/**
     41 * 32-bit darwin kernel module info structure (kmod_info_t).
     42 */
     43typedef struct OSX32_kmod_info
     44{
     45    uint32_t    next;
     46    int32_t     info_version;
     47    uint32_t    id;
     48    char        name[64];
     49    char        version[64];
     50    int32_t     reference_count;
     51    uint32_t    reference_list;         /**< Points to kmod_reference_t. */
     52    uint32_t    address;                /**< Where in memory the kext is loaded. */
     53    uint32_t    size;
     54    uint32_t    hdr_size;
     55    uint32_t    start;                  /**< Address of kmod_start_func_t. */
     56    uint32_t    stop;                   /**< Address of kmod_stop_func_t. */
     57} OSX32_kmod_info_t;
     58
     59/**
     60 * 32-bit darwin kernel module info structure (kmod_info_t).
     61 */
     62#pragma pack(1)
     63typedef struct OSX64_kmod_info
     64{
     65    uint64_t    next;
     66    int32_t     info_version;
     67    uint32_t    id;
     68    char        name[64];
     69    char        version[64];
     70    int32_t     reference_count;
     71    uint64_t    reference_list;         /**< Points to kmod_reference_t. Misaligned, duh. */
     72    uint64_t    address;                /**< Where in memory the kext is loaded. */
     73    uint64_t    size;
     74    uint64_t    hdr_size;
     75    uint64_t    start;                  /**< Address of kmod_start_func_t. */
     76    uint64_t    stop;                   /**< Address of kmod_stop_func_t. */
     77} OSX64_kmod_info_t;
     78#pragma pack()
     79
     80/** The value of the info_version field. */
     81#define OSX_KMOD_INFO_VERSION   INT32_C(1)
    4082
    4183/** @} */
     
    65107*   Defined Constants And Macros                                               *
    66108*******************************************************************************/
    67 /** Validates a 32-bit linux kernel address */
    68 #define DARWIN32_VALID_ADDRESS(Addr)    ((Addr) > UINT32_C(0x80000000) && (Addr) < UINT32_C(0xfffff000))
    69 
    70 /** The max kernel size. */
    71 #define DARWIN_MAX_KERNEL_SIZE          0x0f000000
     109/** Validates a 32-bit darwin kernel address */
     110#define OSX32_VALID_ADDRESS(Addr)    ((Addr) > UINT32_C(0x00001000) && (Addr) < UINT32_C(0xfffff000))
     111/** Validates a 64-bit darwin kernel address */
     112#define OSX64_VALID_ADDRESS(Addr)    ((Addr) > UINT64_C(0xffff800000000000) && (Addr) < UINT32_C(0xfffffffffffff000))
     113/** Validates a 32-bit or 64-bit darwin kernel address. */
     114#define OSX_VALID_ADDRESS(a_f64Bits, a_Addr) \
     115    ((a_f64Bits) ? OSX64_VALID_ADDRESS(a_Addr) : OSX32_VALID_ADDRESS(a_Addr))
    72116
    73117/** AppleOsX on little endian ASCII systems. */
     
    79123*******************************************************************************/
    80124static DECLCALLBACK(int)  dbgDiggerDarwinInit(PUVM pUVM, void *pvData);
    81 
    82 
    83 /*******************************************************************************
    84 *   Global Variables                                                           *
    85 *******************************************************************************/
    86 /** Table of common linux kernel addresses. */
    87 static uint64_t g_au64LnxKernelAddresses[] =
    88 {
    89     UINT64_C(0xc0100000),
    90     UINT64_C(0x90100000),
    91     UINT64_C(0xffffffff80200000)
    92 };
    93125
    94126
     
    193225
    194226
    195 static int dbgDiggerDarwinAddModule(PDBGDIGGERDARWIN pThis, PUVM pUVM, uint64_t uModAddr, const char *pszName)
     227static int dbgDiggerDarwinAddModule(PDBGDIGGERDARWIN pThis, PUVM pUVM, uint64_t uModAddr, const char *pszName, bool *pf64Bit)
    196228{
    197229    union
     
    416448    else
    417449        rc = VERR_INTERNAL_ERROR;
     450
    418451    RTDbgModRelease(hMod);
    419452    RTDbgAsRelease(hAs);
    420453
     454    if (pf64Bit)
     455        *pf64Bit = f64Bit;
    421456    return rc;
    422457}
     458
     459
     460static bool dbgDiggerDarwinIsValidName(const char *pszName)
     461{
     462    char ch;
     463    while ((ch = *pszName++) != '\0')
     464    {
     465        if (ch < 0x20 || ch >= 127)
     466            return false;
     467    }
     468    return true;
     469}
     470
     471
     472static bool dbgDiggerDarwinIsValidVersion(const char *pszVersion)
     473{
     474    char ch;
     475    while ((ch = *pszVersion++) != '\0')
     476    {
     477        if (ch < 0x20 || ch >= 127)
     478            return false;
     479    }
     480    return true;
     481}
     482
    423483
    424484/**
     
    431491
    432492    /*
    433      * Add the kernel module (and later the other kernel modules we can find).
     493     * Add the kernel module.
    434494     */
    435     int rc = dbgDiggerDarwinAddModule(pThis, pUVM, pThis->AddrKernel.FlatPtr, "mach_kernel");
     495    bool f64Bit;
     496    int rc = dbgDiggerDarwinAddModule(pThis, pUVM, pThis->AddrKernel.FlatPtr, "mach_kernel", &f64Bit);
    436497    if (RT_SUCCESS(rc))
    437498    {
    438         /** @todo  */
     499        /*
     500         * The list of modules can be found at the 'kmod' symbol, that means
     501         * that we currently require some kind of symbol file for the kernel
     502         * to be loaded at this point.
     503         *
     504         * Note! Could also use the 'gLoadedKextSummaries', but I don't think
     505         *       it's any easier to find without any kernel map than 'kmod'.
     506         */
     507        RTDBGSYMBOL SymInfo;
     508        rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_KERNEL, "mach_kernel!kmod", &SymInfo, NULL);
     509        if (RT_FAILURE(rc))
     510            rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_KERNEL, "mach_kernel!_kmod", &SymInfo, NULL);
     511        if (RT_SUCCESS(rc))
     512        {
     513            DBGFADDRESS AddrModInfo;
     514            DBGFR3AddrFromFlat(pUVM, &AddrModInfo, SymInfo.Value);
     515
     516            /* Read the variable. */
     517            RTUINT64U uKmodValue = { 0 };
     518            if (f64Bit)
     519                rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &AddrModInfo, &uKmodValue.u, sizeof(uKmodValue.u));
     520            else
     521                rc = DBGFR3MemRead (pUVM, 0 /*idCpu*/, &AddrModInfo, &uKmodValue.s.Lo, sizeof(uKmodValue.s.Lo));
     522            if (RT_SUCCESS(rc))
     523            {
     524                DBGFR3AddrFromFlat(pUVM, &AddrModInfo, uKmodValue.u);
     525
     526                /* Walk the list of modules. */
     527                uint32_t cIterations = 0;
     528                while (AddrModInfo.FlatPtr != 0)
     529                {
     530                    /* Some extra loop conditions... */
     531                    if (!OSX_VALID_ADDRESS(f64Bit, AddrModInfo.FlatPtr))
     532                    {
     533                        Log(("OSXDig: Invalid kmod_info pointer: %RGv\n", AddrModInfo.FlatPtr));
     534                        break;
     535                    }
     536                    if (AddrModInfo.FlatPtr == uKmodValue.u && cIterations != 0)
     537                    {
     538                        Log(("OSXDig: kmod_info list looped back to the start.\n"));
     539                        break;
     540                    }
     541                    if (cIterations++ >= 2048)
     542                    {
     543                        Log(("OSXDig: Too many mod_info loops (%u)\n", cIterations));
     544                        break;
     545                    }
     546
     547                    /*
     548                     * Read the kmod_info_t structure.
     549                     */
     550                    union
     551                    {
     552                        OSX64_kmod_info_t   Info64;
     553                        OSX32_kmod_info_t   Info32;
     554                    } uMod;
     555                    RT_ZERO(uMod);
     556                    rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &AddrModInfo, &uMod,
     557                                       f64Bit ? sizeof(uMod.Info64) : sizeof(uMod.Info64));
     558                    if (RT_FAILURE(rc))
     559                    {
     560                        Log(("OSXDig: Error reading kmod_info structure at %RGv: %Rrc\n", AddrModInfo.FlatPtr, rc));
     561                        break;
     562                    }
     563
     564                    /*
     565                     * Validate the kmod_info_t structure.
     566                     */
     567                    int32_t iInfoVer = f64Bit ? uMod.Info64.info_version : uMod.Info32.info_version;
     568                    if (iInfoVer != OSX_KMOD_INFO_VERSION)
     569                    {
     570                        Log(("OSXDig: kmod_info @%RGv: Bad info_version %d\n", AddrModInfo.FlatPtr, iInfoVer));
     571                        break;
     572                    }
     573
     574                    const char *pszName = f64Bit ? uMod.Info64.name : uMod.Info32.name;
     575                    if (   !*pszName
     576                        || !RTStrEnd(pszName, sizeof(uMod.Info64.name))
     577                        || !dbgDiggerDarwinIsValidName(pszName) )
     578                    {
     579                        Log(("OSXDig: kmod_info @%RGv: Bad name '%.*s'\n", AddrModInfo.FlatPtr,
     580                             sizeof(uMod.Info64.name), pszName));
     581                        break;
     582                    }
     583
     584                    const char *pszVersion = f64Bit ? uMod.Info64.version : uMod.Info32.version;
     585                    if (   !RTStrEnd(pszVersion, sizeof(uMod.Info64.version))
     586                        || !dbgDiggerDarwinIsValidVersion(pszVersion) )
     587                    {
     588                        Log(("OSXDig: kmod_info @%RGv: Bad version '%.*s'\n", AddrModInfo.FlatPtr,
     589                             sizeof(uMod.Info64.version), pszVersion));
     590                        break;
     591                    }
     592
     593                    int32_t cRefs = f64Bit ? uMod.Info64.reference_count : uMod.Info32.reference_count;
     594                    if (cRefs < -1 || cRefs > 16384)
     595                    {
     596                        Log(("OSXDig: kmod_info @%RGv: Bad reference_count %d\n", AddrModInfo.FlatPtr, cRefs));
     597                        break;
     598                    }
     599
     600                    uint64_t uImageAddr = f64Bit ? uMod.Info64.address : uMod.Info32.address;
     601                    if (!OSX_VALID_ADDRESS(f64Bit, uImageAddr))
     602                    {
     603                        Log(("OSXDig: kmod_info @%RGv: Bad address %#llx\n", AddrModInfo.FlatPtr, uImageAddr));
     604                        break;
     605                    }
     606
     607                    uint64_t cbImage = f64Bit ? uMod.Info64.size : uMod.Info32.size;
     608                    if (cbImage > 64U*_1M)
     609                    {
     610                        Log(("OSXDig: kmod_info @%RGv: Bad size %#llx\n", AddrModInfo.FlatPtr, cbImage));
     611                        break;
     612                    }
     613
     614                    uint64_t cbHdr = f64Bit ? uMod.Info64.hdr_size : uMod.Info32.hdr_size;
     615                    if (cbHdr > 16U*_1M)
     616                    {
     617                        Log(("OSXDig: kmod_info @%RGv: Bad hdr_size %#llx\n", AddrModInfo.FlatPtr, cbHdr));
     618                        break;
     619                    }
     620
     621                    uint64_t uStartAddr = f64Bit ? uMod.Info64.start : uMod.Info32.start;
     622                    if (!uStartAddr && !OSX_VALID_ADDRESS(f64Bit, uStartAddr))
     623                    {
     624                        Log(("OSXDig: kmod_info @%RGv: Bad start function %#llx\n", AddrModInfo.FlatPtr, uStartAddr));
     625                        break;
     626                    }
     627
     628                    uint64_t uStopAddr = f64Bit ? uMod.Info64.stop : uMod.Info32.stop;
     629                    if (!uStopAddr && !OSX_VALID_ADDRESS(f64Bit, uStopAddr))
     630                    {
     631                        Log(("OSXDig: kmod_info @%RGv: Bad stop function %#llx\n", AddrModInfo.FlatPtr, uStopAddr));
     632                        break;
     633                    }
     634
     635                    /*
     636                     * Try add the module.
     637                     */
     638                    Log(("OSXDig: kmod_info @%RGv: '%s' ver '%s', image @%#llx LB %#llx cbHdr=%#llx\n",
     639                         pszName, pszVersion, uImageAddr, cbImage, cbHdr));
     640                    rc = dbgDiggerDarwinAddModule(pThis, pUVM, uImageAddr, pszName, NULL);
     641
     642
     643                    /*
     644                     * Advance to the next kmod_info entry.
     645                     */
     646                    DBGFR3AddrFromFlat(pUVM, &AddrModInfo, f64Bit ? uMod.Info64.next : uMod.Info32.next);
     647                }
     648            }
     649            else
     650                Log(("OSXDig: Error reading the 'kmod' variable: %Rrc\n", rc));
     651        }
     652        else
     653            Log(("OSXDig: Failed to locate the 'kmod' variable in mach_kernel.\n"));
     654
    439655        pThis->fValid = true;
    440656        return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

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