VirtualBox

Changeset 86701 in vbox for trunk/src/VBox/VMM/VMMRZ


Ignore:
Timestamp:
Oct 25, 2020 6:20:09 PM (4 years ago)
Author:
vboxsync
Message:

VMM/DBGF: Start implementing support for int3 breakpoints, bugref:9837

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMRZ/DBGFRZ.cpp

    r86666 r86701  
    190190}
    191191
     192#ifdef VBOX_WITH_LOTS_OF_DBGF_BPS
     193# ifdef IN_RING0
     194/**
     195 * Returns the internal breakpoint state for the given handle.
     196 *
     197 * @returns Pointer to the internal breakpoint state or NULL if the handle is invalid.
     198 * @param   pVM                 The ring-0 VM structure pointer.
     199 * @param   hBp                 The breakpoint handle to resolve.
     200 * @param   ppBpR0              Where to store the pointer to the ring-0 only part of the breakpoint
     201 *                              on success, optional.
     202 */
     203DECLINLINE(PDBGFBPINT) dbgfR0BpGetByHnd(PVMCC pVM, DBGFBP hBp, PDBGFBPINTR0 *ppBpR0)
     204{
     205    uint32_t idChunk  = DBGF_BP_HND_GET_CHUNK_ID(hBp);
     206    uint32_t idxEntry = DBGF_BP_HND_GET_ENTRY(hBp);
     207
     208    AssertReturn(idChunk < DBGF_BP_CHUNK_COUNT, NULL);
     209    AssertReturn(idxEntry < DBGF_BP_COUNT_PER_CHUNK, NULL);
     210
     211    PDBGFBPCHUNKR0 pBpChunk = &pVM->dbgfr0.s.aBpChunks[idChunk];
     212    AssertPtrReturn(pBpChunk->paBpBaseSharedR0, NULL);
     213
     214    if (ppBpR0)
     215        *ppBpR0 = &pBpChunk->paBpBaseR0Only[idxEntry];
     216    return &pBpChunk->paBpBaseSharedR0[idxEntry];
     217}
     218# endif
     219
     220
     221/**
     222 * Executes the actions associated with the given breakpoint.
     223 *
     224 * @returns VBox status code.
     225 * @param   pVM         The cross context VM structure.
     226 * @param   pVCpu       The cross context virtual CPU structure.
     227 * @param   pRegFrame   Pointer to the register frame for the trap.
     228 * @param   hBp         The breakpoint handle which hit.
     229 * @param   pBp         The shared breakpoint state.
     230 * @param   pBpR0       The ring-0 only breakpoint state.
     231 * @param   fInHyper    Flag whether the breakpoint triggered in hypervisor code.
     232 */
     233DECLINLINE(int) dbgfRZBpHit(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame,
     234                            DBGFBP hBp, PDBGFBPINT pBp, PDBGFBPINTR0 pBpR0, bool fInHyper)
     235{
     236    uint64_t cHits = ASMAtomicIncU64(&pBp->Pub.cHits);
     237    pVCpu->dbgf.s.hBpActive = hBp;
     238
     239    /** @todo Owner handling. */
     240
     241    LogFlow(("dbgfRZBpHit: hit breakpoint %u at %04x:%RGv cHits=0x%RX64\n",
     242             hBp, pRegFrame->cs.Sel, pRegFrame->rip, cHits));
     243    return fInHyper
     244         ? VINF_EM_DBG_HYPER_BREAKPOINT
     245         : VINF_EM_DBG_BREAKPOINT;
     246}
     247#endif /* !VBOX_WITH_LOTS_OF_DBGF_BPS */
    192248
    193249/**
     
    202258 * @param   pRegFrame   Pointer to the register frame for the trap.
    203259 */
    204 VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame)
     260VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame)
    205261{
    206262#ifdef IN_RC
     
    247303        }
    248304    }
     305#else
     306# ifdef IN_RC
     307# error "You lucky person have the pleasure to implement the raw mode part for this!"
     308# endif
     309
     310    if (pVM->dbgfr0.s.CTX_SUFF(paBpLocL1))
     311    {
     312        RTGCPTR GCPtrBp;
     313        int rc = SELMValidateAndConvertCSAddr(pVCpu, pRegFrame->eflags, pRegFrame->ss.Sel, pRegFrame->cs.Sel, &pRegFrame->cs,
     314# ifdef IN_RC
     315                                              pRegFrame->eip - 1,
     316# else
     317                                              pRegFrame->rip /* no -1 in R0 */,
     318# endif
     319                                              &GCPtrBp);
     320        AssertRCReturn(rc, rc);
     321
     322        const uint16_t idxL1      = DBGF_BP_INT3_L1_IDX_EXTRACT_FROM_ADDR(GCPtrBp);
     323        const uint32_t u32L1Entry = ASMAtomicReadU32(&pVM->dbgfr0.s.CTX_SUFF(paBpLocL1)[idxL1]);
     324
     325        LogFlowFunc(("GCPtrBp=%RGv idxL1=%u u32L1Entry=%#x\n", GCPtrBp, idxL1, u32L1Entry));
     326        if (u32L1Entry != DBGF_BP_INT3_L1_ENTRY_TYPE_NULL)
     327        {
     328            uint8_t u8Type = DBGF_BP_INT3_L1_ENTRY_GET_TYPE(u32L1Entry);
     329            if (u8Type == DBGF_BP_INT3_L1_ENTRY_TYPE_BP_HND)
     330            {
     331                DBGFBP hBp = DBGF_BP_INT3_L1_ENTRY_GET_BP_HND(u32L1Entry);
     332
     333                /* Query the internal breakpoint state from the handle. */
     334                PDBGFBPINTR0 pBpR0 = NULL;
     335                PDBGFBPINT pBp = dbgfR0BpGetByHnd(pVM, hBp, &pBpR0);
     336                if (   pBp
     337                    && DBGF_BP_PUB_GET_TYPE(pBp->Pub.fFlagsAndType) == DBGFBPTYPE_INT3)
     338                {
     339                    if (pBp->Pub.u.Int3.GCPtr == (RTGCUINTPTR)GCPtrBp)
     340                        return dbgfRZBpHit(pVM, pVCpu, pRegFrame, hBp, pBp, pBpR0, fInHyper);
     341                    /* else Genuine guest trap. */
     342                }
     343                /** @todo else Guru meditation */
     344            }
     345            else if (u8Type == DBGF_BP_INT3_L1_ENTRY_TYPE_L2_IDX)
     346            {
     347                /** @todo Walk the L2 tree searching for the correct spot. */
     348            }
     349            /** @todo else Guru meditation */
     350        }
     351    }
    249352#endif /* !VBOX_WITH_LOTS_OF_DBGF_BPS */
    250353
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