Ignore:
Timestamp:
Mar 17, 2012, 11:02:20 PM (13 years ago)
Author:
dmik
Message:

kernel32: Support guard page exceptions.

This is in particular necessary for Java yellow and red zone
implementations.

Coses #76.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/exceptions.cpp

    r21916 r21980  
    16381638
    16391639        if(teb == NULL) {
    1640             goto continueGuardException;
     1640            goto continuesearch;
    16411641        }
    16421642
     
    16471647        stacktop    = stacktop & ~0xFFF;
    16481648
    1649         //Make sure we detect a stack overflow condition before the system does
    1650         if(!fIsOS2Image &&
     1649        // Make sure we detect a stack overflow condition before the system does
     1650        if ((!fIsOS2Image || fSEHEnabled) && //Only for real win32 apps or if SEH enabled
    16511651            pERepRec->ExceptionInfo[1]  >= stackbottom &&
    16521652            pERepRec->ExceptionInfo[1]  <  stacktop
    16531653           )
    1654         {//this is a guard page exception for the thread stack
     1654        {
     1655            // this is a guard page exception for the thread stack
     1656
     1657            // In order to imitate Windows behavior, we must raise
     1658            // EXCEPTION_STACK_OVERFLOW in the Win32 context in two cases:
     1659            // 1. When we run out of stack.
     1660            // 2. When a guard page not immediately following the committed
     1661            //    stack area is touched.
     1662
    16551663            APIRET rc;
    1656             ULONG ulAddress, cbSize, ulMemFlags;
    1657 
    1658             //round down to page boundary
    1659             ulAddress = pERepRec->ExceptionInfo[1] & ~0xFFF;
    1660 
    1661 #if 0
    1662             rc = DosQueryMem((PVOID)ulAddress, &cbSize, &ulMemFlags);
    1663             if(rc) {
    1664                 dprintf(("ERROR: DosQueryMem old guard page failed with rc %d", rc));
    1665                 goto continueGuardException;
     1664            BOOL bRaise = FALSE;
     1665
     1666            // round down to page boundary
     1667            ULONG ulAddress = pERepRec->ExceptionInfo[1] & ~0xFFF;
     1668
     1669            if (ulAddress == stackbottom + PAGE_SIZE)
     1670            {
     1671                // we are about to run out of stack
     1672                bRaise = TRUE;
    16661673            }
    1667 #endif
    1668 
    1669             if(ulAddress == stackbottom + PAGE_SIZE)
    1670             {//we don't have any stack left, throw an XCPT_UNABLE_TO_GROW_STACK
    1671              //exception
    1672                 if(!fExitProcess)  //Only for real win32 apps
     1674            else
     1675            {
     1676                // check if it's an adjacent guard page used to grow stack
     1677                ULONG cbSize = ~0, ulMemFlags;
     1678                rc = DosQueryMem((PVOID)ulAddress, &cbSize, &ulMemFlags);
     1679                if (rc)
     1680                {
     1681                    dprintf(("ERROR: DosQueryMem old guard page failed with rc %d", rc));
     1682                    goto continueGuardException;
     1683                }
     1684
     1685                if (ulAddress + cbSize == stacktop)
     1686                {
     1687                    // yes, we must pass it on to the system to do the grow magic
     1688                    goto continuesearch;
     1689                }
     1690
     1691                bRaise = TRUE;
     1692            }
     1693
     1694            if (bRaise)
     1695            {
     1696                if (!fExitProcess)
    16731697                {
    16741698                    EXCEPTIONREPORTRECORD recoutofstack;
     
    16881712        }
    16891713        else
    1690         {//check for memory map guard page exception
    1691         Win32MemMap *map;
    1692         BOOL  fWriteAccess = FALSE, ret;
    1693         ULONG offset, accessflag;
    1694 
    1695         switch(pERepRec->ExceptionInfo[0]) {
    1696         case XCPT_READ_ACCESS:
     1714        {
     1715            // Throw EXCEPTION_GUARD_PAGE_VIOLATION in the Win32 context
     1716            if((!fIsOS2Image || fSEHEnabled) && !fExitProcess)  //Only for real win32 apps or if SEH enabled
     1717            {
     1718                if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE)
     1719                {
     1720                    goto continueexecution;
     1721                }
     1722            }
     1723
     1724            //check for memory map guard page exception
     1725            Win32MemMap *map;
     1726            BOOL  fWriteAccess = FALSE, ret;
     1727            ULONG offset, accessflag;
     1728
     1729            switch(pERepRec->ExceptionInfo[0]) {
     1730            case XCPT_READ_ACCESS:
    16971731                accessflag = MEMMAP_ACCESS_READ;
    16981732                break;
    1699         case XCPT_WRITE_ACCESS:
     1733            case XCPT_WRITE_ACCESS:
    17001734                accessflag = MEMMAP_ACCESS_WRITE;
    17011735                fWriteAccess = TRUE;
    17021736                break;
    1703         default:
     1737            default:
    17041738                goto continueGuardException;
    1705         }
    1706 
    1707         map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag);
     1739            }
     1740
     1741            map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag);
    17081742            if(map) {
    1709         ret = map->commitGuardPage(pERepRec->ExceptionInfo[1], offset, fWriteAccess);
    1710         map->Release();
    1711         if(ret == TRUE)
    1712             goto continueexecution;
     1743                ret = map->commitGuardPage(pERepRec->ExceptionInfo[1], offset, fWriteAccess);
     1744                map->Release();
     1745                if(ret == TRUE)
     1746                    goto continueexecution;
    17131747            }
    17141748        }
Note: See TracChangeset for help on using the changeset viewer.