VirtualBox

Changeset 2871 in kBuild


Ignore:
Timestamp:
Sep 4, 2016 6:32:57 PM (8 years ago)
Author:
bird
Message:

x86 exception dispatching.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r2869 r2871  
    398398    /** The exit code in case of longjmp.   */
    399399    int         rcExitCode;
     400    /** Set if we're running. */
     401    KBOOL       fRunning;
    400402
    401403    /** The command line.   */
     
    46684670
    46694671
     4672#if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86)
     4673typedef struct _EXCEPTION_REGISTRATION_RECORD
     4674{
     4675    struct _EXCEPTION_REGISTRATION_RECORD * volatile PrevStructure;
     4676    KU32 (__cdecl * volatile ExceptionHandler)(PEXCEPTION_RECORD, struct _EXCEPTION_REGISTRATION_RECORD*, PCONTEXT,
     4677                                               struct _EXCEPTION_REGISTRATION_RECORD * volatile *);
     4678};
     4679
     4680/**
     4681 * Vectored exception handler that emulates x86 chained exception handler.
     4682 *
     4683 * This is necessary because the RtlIsValidHandler check fails for self loaded
     4684 * code and prevents cl.exe from working.  (On AMD64 we can register function
     4685 * tables, but on X86 cooking your own handling seems to be the only viabke
     4686 * alternative.)
     4687 *
     4688 * @returns EXCEPTION_CONTINUE_SEARCH or EXCEPTION_CONTINUE_EXECUTION.
     4689 * @param   pXcptPtrs           The exception details.
     4690 */
     4691static LONG CALLBACK kwSandboxVecXcptEmulateChained(PEXCEPTION_POINTERS pXcptPtrs)
     4692{
     4693    PNT_TIB pTib = (PNT_TIB)NtCurrentTeb();
     4694    KW_LOG(("kwSandboxVecXcptEmulateChained: %#x\n", pXcptPtrs->ExceptionRecord->ExceptionCode));
     4695    if (g_Sandbox.fRunning)
     4696    {
     4697        PEXCEPTION_RECORD                                 pXcptRec = pXcptPtrs->ExceptionRecord;
     4698        PCONTEXT                                          pXcptCtx = pXcptPtrs->ContextRecord;
     4699        struct _EXCEPTION_REGISTRATION_RECORD * volatile *ppRegRec = &pTib->ExceptionList;
     4700        struct _EXCEPTION_REGISTRATION_RECORD *           pRegRec  = *ppRegRec;
     4701        while (((KUPTR)pRegRec & (sizeof(void *) - 3)) == 0 && pRegRec != NULL)
     4702        {
     4703#if 1
     4704            /* This is a more robust version that isn't subject to calling
     4705               convension cleanup disputes and such. */
     4706            KU32 uSavedEdi;
     4707            KU32 uSavedEsi;
     4708            KU32 uSavedEbx;
     4709            KU32 rcHandler;
     4710            __asm
     4711            {
     4712                mov     [uSavedEdi], edi
     4713                mov     [uSavedEsi], esi
     4714                mov     [uSavedEbx], ebx
     4715                mov     esi, esp
     4716                mov     edi, esp
     4717                mov     ecx, [pXcptRec]
     4718                mov     edx, [pRegRec]
     4719                mov     eax, [pXcptCtx]
     4720                mov     ebx, [ppRegRec]
     4721                sub     esp, 16
     4722                and     esp, 0fffffff0h
     4723                mov     [esp     ], ecx
     4724                mov     [esp +  4], edx
     4725                mov     [esp +  8], eax
     4726                mov     [esp + 12], ebx
     4727                call    dword ptr [edx + 4]
     4728                mov     esp, esi
     4729                cmp     esp, edi
     4730                je      stack_ok
     4731                int     3
     4732            stack_ok:
     4733                mov     edi, [uSavedEdi]
     4734                mov     esi, [uSavedEsi]
     4735                mov     ebx, [uSavedEbx]
     4736                mov     [rcHandler], eax
     4737            }
     4738#else
     4739            KU32 rcHandler = pRegRec->ExceptionHandler(pXcptPtrs->ExceptionRecord, pRegRec, pXcptPtrs->ContextRecord, ppRegRec);
     4740#endif
     4741            if (rcHandler == ExceptionContinueExecution)
     4742            {
     4743                kHlpAssert(!(pXcptPtrs->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE));
     4744                return EXCEPTION_CONTINUE_EXECUTION;
     4745            }
     4746            if (rcHandler == ExceptionContinueSearch)
     4747                kHlpAssert(!(pXcptPtrs->ExceptionRecord->ExceptionFlags & 8 /*EXCEPTION_STACK_INVALID*/));
     4748            else if (rcHandler == ExceptionNestedException)
     4749                kHlpAssertMsgFailed(("Nested exceptions.\n"));
     4750            else
     4751                kHlpAssertMsgFailed(("Invalid return %#x (%d).\n", rcHandler, rcHandler));
     4752
     4753            /*
     4754             * Next.
     4755             */
     4756            ppRegRec = &pRegRec->PrevStructure;
     4757            pRegRec = pRegRec->PrevStructure;
     4758        }
     4759    }
     4760    return EXCEPTION_CONTINUE_SEARCH;
     4761}
     4762#endif /* WINDOWS + X86 */
     4763
     4764
    46704765/**
    46714766 * Enters the given handle into the handle table.
     
    49055000                /* Save the NT TIB first (should do that here, not in some other function). */
    49065001                PNT_TIB pTib = (PNT_TIB)NtCurrentTeb();
    4907                 g_Sandbox.TibMainThread = *pTib;
     5002                pSandbox->TibMainThread = *pTib;
    49085003
    49095004                /* Make the call in a guarded fashion. */
     
    49145009                {
    49155010                    pSandbox->pOutXcptListHead = pTib->ExceptionList;
    4916                     if (setjmp(g_Sandbox.JmpBuf) == 0)
     5011                    if (setjmp(pSandbox->JmpBuf) == 0)
    49175012                    {
    4918                         *(KU64*)(g_Sandbox.JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */
     5013                        *(KU64*)(pSandbox->JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */
     5014                        pSandbox->fRunning = K_TRUE;
    49195015                        rcExit = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL);
     5016                        pSandbox->fRunning = K_FALSE;
    49205017                    }
    49215018                    else
    4922                         rcExit = g_Sandbox.rcExitCode;
     5019                        rcExit = pSandbox->rcExitCode;
    49235020                }
    49245021#elif K_ARCH == K_ARCH_X86_32
     
    49285025                {
    49295026                    pSandbox->pOutXcptListHead = pTib->ExceptionList;
    4930                     if (setjmp(g_Sandbox.JmpBuf) == 0)
     5027                    if (setjmp(pSandbox->JmpBuf) == 0)
    49315028                    {
    4932                         //*(KU64*)(g_Sandbox.JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */
     5029                        //*(KU64*)(pSandbox->JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */
     5030                        pSandbox->fRunning = K_TRUE;
    49335031                        rcExit = pfnWin32Entrypoint(kwSandboxGetProcessEnvironmentBlock());
     5032                        pSandbox->fRunning = K_FALSE;
    49345033                    }
    49355034                    else
    4936                         rcExit = g_Sandbox.rcExitCode;
     5035                        rcExit = pSandbox->rcExitCode;
    49375036                }
    49385037#endif
     
    49415040                    rcExit = 512;
    49425041                }
     5042                pSandbox->fRunning = K_FALSE;
    49435043
    49445044                /* Now, restore the NT TIB. */
    4945                 *pTib = g_Sandbox.TibMainThread;
     5045                *pTib = pSandbox->TibMainThread;
    49465046            }
    49475047            else
     
    53575457    const char     *pszTmp;
    53585458    KFSLOOKUPERROR  enmIgnored;
     5459#if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86)
     5460    PVOID           pvVecXcptHandler = AddVectoredExceptionHandler(0 /*called last*/, kwSandboxVecXcptEmulateChained);
     5461#endif
    53595462
    53605463    /*
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