VirtualBox

Changeset 97468 in vbox


Ignore:
Timestamp:
Nov 8, 2022 11:47:28 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154478
Message:

VMM/IEM: Wrapped up the setjmp calls and associated 'catch' code into macros and made it possible to replace setjmp/longjmp by try/throw/catch in ring-3 (latter is disabled atm). bugref:9898

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r97467 r97468  
    96829682
    96839683
     9684/** @def IEM_TRY_SETJMP
     9685 * Wrapper around setjmp / try, hiding all the ugly differences.
     9686 *
     9687 * @note Use with extreme care as this is a fragile macro.
     9688 * @param   a_pVCpu     The cross context virtual CPU structure of the calling EMT.
     9689 * @param   a_rcTarget  The variable that should receive the status code in case
     9690 *                      of a longjmp/throw.
     9691 */
     9692/** @def IEM_TRY_SETJMP_AGAIN
     9693 * For when setjmp / try is used again in the same variable scope as a previous
     9694 * IEM_TRY_SETJMP invocation.
     9695 */
     9696/** @def IEM_CATCH_LONGJMP_BEGIN
     9697 * Start wrapper for catch / setjmp-else.
     9698 *
     9699 * This will set up a scope.
     9700 *
     9701 * @note Use with extreme care as this is a fragile macro.
     9702 * @param   a_pVCpu     The cross context virtual CPU structure of the calling EMT.
     9703 * @param   a_rcTarget  The variable that should receive the status code in case
     9704 *                      of a longjmp/throw.
     9705 */
     9706/** @def IEM_CATCH_LONGJMP_END
     9707 * End wrapper for catch / setjmp-else.
     9708 *
     9709 * This will close the scope set up by IEM_CATCH_LONGJMP_BEGIN and clean up the
     9710 * state.
     9711 *
     9712 * @note Use with extreme care as this is a fragile macro.
     9713 * @param   a_pVCpu     The cross context virtual CPU structure of the calling EMT.
     9714 */
     9715#if defined(IEM_WITH_SETJMP) || defined(DOXYGEN_RUNNING)
     9716# ifdef IEM_WITH_THROW_CATCH
     9717#  define IEM_TRY_SETJMP(a_pVCpu, a_rcTarget) \
     9718        a_rcTarget = VINF_SUCCESS; \
     9719        try
     9720#  define IEM_TRY_SETJMP_AGAIN(a_pVCpu, a_rcTarget) \
     9721        IEM_TRY_SETJMP(a_pVCpu, a_rcTarget)
     9722#  define IEM_CATCH_LONGJMP_BEGIN(a_pVCpu, a_rcTarget) \
     9723        catch (int rcThrown) \
     9724        { \
     9725            a_rcTarget = rcThrown
     9726#  define IEM_CATCH_LONGJMP_END(a_pVCpu) \
     9727        } \
     9728        ((void)0)
     9729# else  /* !IEM_WITH_THROW_CATCH */
     9730#  define IEM_TRY_SETJMP(a_pVCpu, a_rcTarget) \
     9731        jmp_buf  JmpBuf; \
     9732        jmp_buf * volatile pSavedJmpBuf = pVCpu->iem.s.CTX_SUFF(pJmpBuf); \
     9733        pVCpu->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf; \
     9734        if ((rcStrict = setjmp(JmpBuf)) == 0)
     9735#  define IEM_TRY_SETJMP_AGAIN(a_pVCpu, a_rcTarget) \
     9736        pSavedJmpBuf = pVCpu->iem.s.CTX_SUFF(pJmpBuf); \
     9737        pVCpu->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf; \
     9738        if ((rcStrict = setjmp(JmpBuf)) == 0)
     9739#  define IEM_CATCH_LONGJMP_BEGIN(a_pVCpu, a_rcTarget) \
     9740        else \
     9741        { \
     9742            ((void)0)
     9743#  define IEM_CATCH_LONGJMP_END(a_pVCpu) \
     9744        } \
     9745        (a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf) = pSavedJmpBuf
     9746# endif /* !IEM_WITH_THROW_CATCH */
     9747#endif  /* IEM_WITH_SETJMP */
     9748
     9749
    96849750/**
    96859751 * The actual code execution bits of IEMExecOne, IEMExecOneEx, and
     
    97039769#ifdef IEM_WITH_SETJMP
    97049770    VBOXSTRICTRC rcStrict;
    9705     jmp_buf      JmpBuf;
    9706     jmp_buf     *pSavedJmpBuf  = pVCpu->iem.s.CTX_SUFF(pJmpBuf);
    9707     pVCpu->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf;
    9708     if ((rcStrict = setjmp(JmpBuf)) == 0)
     9771    IEM_TRY_SETJMP(pVCpu, rcStrict)
    97099772    {
    97109773        uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
    97119774        rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    97129775    }
    9713     else
     9776    IEM_CATCH_LONGJMP_BEGIN(pVCpu, rcStrict);
     9777    {
    97149778        pVCpu->iem.s.cLongJumps++;
    9715     pVCpu->iem.s.CTX_SUFF(pJmpBuf) = pSavedJmpBuf;
     9779    }
     9780    IEM_CATCH_LONGJMP_END(pVCpu);
    97169781#else
    97179782    uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     
    97649829#endif
    97659830#ifdef IEM_WITH_SETJMP
    9766             pVCpu->iem.s.CTX_SUFF(pJmpBuf) = &JmpBuf;
    9767             if ((rcStrict = setjmp(JmpBuf)) == 0)
     9831            IEM_TRY_SETJMP_AGAIN(pVCpu, rcStrict)
    97689832            {
    97699833                uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
    97709834                rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    97719835            }
    9772             else
     9836            IEM_CATCH_LONGJMP_BEGIN(pVCpu, rcStrict);
     9837            {
    97739838                pVCpu->iem.s.cLongJumps++;
    9774             pVCpu->iem.s.CTX_SUFF(pJmpBuf) = pSavedJmpBuf;
     9839            }
     9840            IEM_CATCH_LONGJMP_END(pVCpu);
    97759841#else
    97769842            IEM_OPCODE_GET_NEXT_U8(&b);
     
    1003410100    {
    1003510101#ifdef IEM_WITH_SETJMP
    10036         jmp_buf         JmpBuf;
    10037         jmp_buf        *pSavedJmpBuf = pVCpu->iem.s.CTX_SUFF(pJmpBuf);
    10038         pVCpu->iem.s.CTX_SUFF(pJmpBuf)   = &JmpBuf;
    10039         pVCpu->iem.s.cActiveMappings     = 0;
    10040         if ((rcStrict = setjmp(JmpBuf)) == 0)
     10102        pVCpu->iem.s.cActiveMappings = 0; /** @todo wtf? */
     10103        IEM_TRY_SETJMP(pVCpu, rcStrict)
    1004110104#endif
    1004210105        {
     
    1012310186        }
    1012410187#ifdef IEM_WITH_SETJMP
    10125         else
     10188        IEM_CATCH_LONGJMP_BEGIN(pVCpu, rcStrict);
    1012610189        {
    1012710190            if (pVCpu->iem.s.cActiveMappings > 0)
     
    1013210195            pVCpu->iem.s.cLongJumps++;
    1013310196        }
    10134         pVCpu->iem.s.CTX_SUFF(pJmpBuf) = pSavedJmpBuf;
     10197        IEM_CATCH_LONGJMP_END(pVCpu);
    1013510198#endif
    1013610199
     
    1019910262    {
    1020010263#ifdef IEM_WITH_SETJMP
    10201         jmp_buf         JmpBuf;
    10202         jmp_buf        *pSavedJmpBuf = pVCpu->iem.s.CTX_SUFF(pJmpBuf);
    10203         pVCpu->iem.s.CTX_SUFF(pJmpBuf)   = &JmpBuf;
    10204         pVCpu->iem.s.cActiveMappings     = 0;
    10205         if ((rcStrict = setjmp(JmpBuf)) == 0)
     10264        pVCpu->iem.s.cActiveMappings     = 0; /** @todo wtf?!? */
     10265        IEM_TRY_SETJMP(pVCpu, rcStrict)
    1020610266#endif
    1020710267        {
     
    1031210372        }
    1031310373#ifdef IEM_WITH_SETJMP
    10314         else
     10374        IEM_CATCH_LONGJMP_BEGIN(pVCpu, rcStrict);
    1031510375        {
    1031610376            if (pVCpu->iem.s.cActiveMappings > 0)
     
    1031810378            pVCpu->iem.s.cLongJumps++;
    1031910379        }
    10320         pVCpu->iem.s.CTX_SUFF(pJmpBuf) = pSavedJmpBuf;
     10380        IEM_CATCH_LONGJMP_END(pVCpu);
    1032110381#endif
    1032210382
  • TabularUnified trunk/src/VBox/VMM/include/IEMInternal.h

    r97467 r97468  
    6767#endif
    6868
     69/** @def IEM_WITH_THROW_CATCH
     70 * Enables using C++ throw/catch as an alternative to setjmp/longjmp in user
     71 * mode code when IEM_WITH_SETJMP is in effect. */
     72#if (defined(IEM_WITH_SETJMP) && defined(IN_RING3) && 0) || defined(DOXYGEN_RUNNING)
     73# define IEM_WITH_THROW_CATCH
     74#endif
     75
    6976/** @def IEM_DO_LONGJMP
    7077 *
     
    7582 */
    7683#if defined(IEM_WITH_SETJMP) || defined(DOXYGEN_RUNNING)
    77 # define IEM_DO_LONGJMP(a_pVCpu, a_rc)  longjmp(*(a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf), (a_rc))
     84# ifdef IEM_WITH_THROW_CATCH
     85#  define IEM_DO_LONGJMP(a_pVCpu, a_rc)  throw int(a_rc)
     86# else
     87#  define IEM_DO_LONGJMP(a_pVCpu, a_rc)  longjmp(*(a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf), (a_rc))
     88# endif
    7889#endif
    7990
     
    108119 * @see https://developercommunity.visualstudio.com/t/fragile-behavior-of-longjmp-called-from-noexcept-f/1532859
    109120 */
    110 #if defined(_MSC_VER) && defined(IEM_WITH_SETJMP)
     121#if defined(IEM_WITH_SETJMP) && (defined(_MSC_VER) || defined(IEM_WITH_THROW_CATCH))
    111122# define IEM_NOEXCEPT_MAY_LONGJMP   RT_NOEXCEPT_EX(false)
    112123#else
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