VirtualBox

Changeset 54232 in vbox


Ignore:
Timestamp:
Feb 17, 2015 2:43:41 PM (10 years ago)
Author:
vboxsync
Message:

DBGPlugInDarwin.cpp: Quick dmesg implementation hacked up during the meeting.

File:
1 edited

Legend:

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

    r52838 r54232  
    9393    bool fValid;
    9494
     95    /** Set if 64-bit kernel, clear if 32-bit.
     96     *  Set during probing. */
     97    bool f64Bit;
    9598    /** The address of an kernel version string (there are several).
    9699     * This is set during probing. */
     
    99102     * This is set during probing. */
    100103    DBGFADDRESS AddrKernel;
     104
     105    /** The kernel message log interface. */
     106    DBGFOSIDMESG IDmesg;
    101107} DBGDIGGERDARWIN;
    102108/** Pointer to the linux guest OS digger instance data. */
     
    126132
    127133/**
     134 * @interface_method_impl{DBGFOSIDMESG,pfnQueryKernelLog}
     135 */
     136static DECLCALLBACK(int) dbgDiggerDarwinIDmsg_QueryKernelLog(PDBGFOSIDMESG pThis, PUVM pUVM, uint32_t fFlags, uint32_t cMessages,
     137                                                             char *pszBuf, size_t cbBuf, size_t *pcbActual)
     138{
     139    PDBGDIGGERDARWIN pData = RT_FROM_MEMBER(pThis, DBGDIGGERDARWIN, IDmesg);
     140
     141    if (cMessages < 1)
     142        return VERR_INVALID_PARAMETER;
     143
     144    /*
     145     * The 'msgbufp' variable points to a struct msgbuf (bsd/kern/subr_log.c).
     146     */
     147    RTDBGAS  hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
     148    RTDBGMOD hMod;
     149    int rc = RTDbgAsModuleByName(hAs, "mach_kernel", 0, &hMod);
     150    if (RT_FAILURE(rc))
     151        return VERR_NOT_FOUND;
     152    RTDbgAsRelease(hAs);
     153
     154    DBGFADDRESS Addr;
     155    RTGCPTR     GCPtrMsgBufP = 0;
     156    RTDBGSYMBOL SymInfo;
     157    rc = RTDbgModSymbolByName(hMod, "_msgbufp", &SymInfo);
     158    if (RT_SUCCESS(rc))
     159    {
     160        rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, SymInfo.Value + pData->AddrKernel.FlatPtr),
     161                           &GCPtrMsgBufP, pData->f64Bit ? sizeof(uint64_t) : sizeof(uint32_t));
     162        if (RT_FAILURE(rc))
     163        {
     164            Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: failed to read _msgbufp at %RGv: %Rrc\n", Addr.FlatPtr, rc));
     165            return VERR_NOT_FOUND;
     166        }
     167        if (!OSX_VALID_ADDRESS(pData->f64Bit, GCPtrMsgBufP))
     168        {
     169            Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Invalid address for _msgbufp: %RGv\n", GCPtrMsgBufP));
     170            return VERR_NOT_FOUND;
     171        }
     172    }
     173    else
     174    {
     175        rc = RTDbgModSymbolByName(hMod, "_msgbuf", &SymInfo);
     176        if (RT_FAILURE(rc))
     177        {
     178            Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: failed to find _msgbufp and _msgbuf: %Rrc\n", rc));
     179            return VERR_NOT_FOUND;
     180        }
     181        GCPtrMsgBufP = SymInfo.Value + pData->AddrKernel.FlatPtr;
     182        if (!OSX_VALID_ADDRESS(pData->f64Bit, GCPtrMsgBufP))
     183        {
     184            Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Invalid address for _msgbuf: %RGv\n", GCPtrMsgBufP));
     185            return VERR_NOT_FOUND;
     186        }
     187    }
     188
     189    /*
     190     * Read the msgbuf structure.
     191     */
     192    struct
     193    {
     194        uint32_t msg_magic;
     195        uint32_t msg_size;
     196        uint32_t msg_bufx;
     197        uint32_t msg_bufr;
     198        uint64_t msg_bufc; /**< Size depends on windows size. */
     199    } MsgBuf;
     200    rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, GCPtrMsgBufP),
     201                       &GCPtrMsgBufP, sizeof(MsgBuf) - (pData->f64Bit ? 0 : sizeof(uint32_t)) );
     202    if (RT_FAILURE(rc))
     203    {
     204        Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: failed to read msgbuf struct at %RGv: %Rrc\n", Addr.FlatPtr, rc));
     205        return VERR_NOT_FOUND;
     206    }
     207    if (!pData->f64Bit)
     208        MsgBuf.msg_bufc &= UINT32_MAX;
     209
     210    /*
     211     * Validate the structure.
     212     */
     213    if (   MsgBuf.msg_magic != UINT32_C(0x63061)
     214        || MsgBuf.msg_size < UINT32_C(4096)
     215        || MsgBuf.msg_size > 16*_1M
     216        || MsgBuf.msg_bufx > MsgBuf.msg_size
     217        || MsgBuf.msg_bufr > MsgBuf.msg_size
     218        || !OSX_VALID_ADDRESS(pData->f64Bit, MsgBuf.msg_bufc) )
     219    {
     220        Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Invalid MsgBuf data: magic=%#x size=%#x bufx=%#x bufr=%#x bufc=%RGv\n",
     221             MsgBuf.msg_magic, MsgBuf.msg_size, MsgBuf.msg_bufx, MsgBuf.msg_bufr, MsgBuf.msg_bufc));
     222        return VERR_INVALID_STATE;
     223    }
     224
     225    /*
     226     * Read the buffer.
     227     */
     228    char *pchMsgBuf = (char *)RTMemAlloc(MsgBuf.msg_size);
     229    if (!pchMsgBuf)
     230    {
     231        Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Failed to allocate %#x bytes of memory for the log buffer\n",
     232             MsgBuf.msg_size));
     233        return VERR_INVALID_STATE;
     234    }
     235    rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, MsgBuf.msg_bufc), pchMsgBuf, MsgBuf.msg_size);
     236    if (RT_SUCCESS(rc))
     237    {
     238        /*
     239         * Copy it out raw.
     240         */
     241        uint32_t offDst = 0;
     242        if (MsgBuf.msg_bufr < MsgBuf.msg_bufx)
     243        {
     244            /* Single chunk between the read and write offsets. */
     245            uint32_t cbToCopy = MsgBuf.msg_bufx - MsgBuf.msg_bufr;
     246            if (cbToCopy < cbBuf)
     247            {
     248                memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbToCopy);
     249                pszBuf[cbToCopy] = '\0';
     250                rc = VINF_SUCCESS;
     251            }
     252            else
     253            {
     254                if (cbBuf)
     255                {
     256                    memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbBuf - 1);
     257                    pszBuf[cbBuf - 1] = '\0';
     258                }
     259                rc = VERR_BUFFER_OVERFLOW;
     260            }
     261            offDst = cbToCopy + 1;
     262        }
     263        else
     264        {
     265            /* Two chunks, read offset to end, start to write offset. */
     266            uint32_t cbFirst  = MsgBuf.msg_size - MsgBuf.msg_bufr;
     267            uint32_t cbSecond = MsgBuf.msg_bufx;
     268            if (cbFirst + cbSecond < cbBuf)
     269            {
     270                memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbFirst);
     271                memcpy(&pszBuf[cbFirst], pchMsgBuf, cbSecond);
     272                offDst = cbFirst + cbSecond;
     273                pszBuf[offDst++] = '\0';
     274                rc = VINF_SUCCESS;
     275            }
     276            else
     277            {
     278                offDst = cbFirst + cbSecond + 1;
     279                if (cbFirst < cbBuf)
     280                {
     281                    memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbFirst);
     282                    memcpy(&pszBuf[cbFirst], pchMsgBuf, cbBuf - cbFirst);
     283                    pszBuf[cbBuf - 1] = '\0';
     284                }
     285                else if (cbBuf)
     286                {
     287                    memcpy(pszBuf, &pchMsgBuf[MsgBuf.msg_bufr], cbBuf - 1);
     288                    pszBuf[cbBuf - 1] = '\0';
     289                }
     290                rc = VERR_BUFFER_OVERFLOW;
     291            }
     292        }
     293
     294        if (pcbActual)
     295            *pcbActual = offDst;
     296    }
     297    else
     298        Log(("dbgDiggerDarwinIDmsg_QueryKernelLog: Error reading %#x bytes at %RGv: %Rrc\n", MsgBuf.msg_size, MsgBuf.msg_bufc));
     299    RTMemFree(pchMsgBuf);
     300    return rc;
     301}
     302
     303
     304/**
    128305 * @copydoc DBGFOSREG::pfnQueryInterface
    129306 */
    130307static DECLCALLBACK(void *) dbgDiggerDarwinQueryInterface(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf)
    131308{
    132     return NULL;
     309    PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData;
     310    switch (enmIf)
     311    {
     312        case DBGFOSINTERFACE_DMESG:
     313            return &pThis->IDmesg;
     314
     315        default:
     316            return NULL;
     317    }
    133318}
    134319
     
    739924               sure there is a kernel version string in the right one. */
    740925            pThis->AddrKernel = KernelAddr;
     926            pThis->f64Bit     = f64Bit;
    741927
    742928            /*
     
    768954static DECLCALLBACK(int)  dbgDiggerDarwinConstruct(PUVM pUVM, void *pvData)
    769955{
     956    PDBGDIGGERDARWIN pThis = (PDBGDIGGERDARWIN)pvData;
     957
     958    pThis->IDmesg.u32Magic = DBGFOSIDMESG_MAGIC;
     959    pThis->IDmesg.pfnQueryKernelLog = dbgDiggerDarwinIDmsg_QueryKernelLog;
     960    pThis->IDmesg.u32EndMagic = DBGFOSIDMESG_MAGIC;
     961
    770962    return VINF_SUCCESS;
    771963}
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