VirtualBox

Ignore:
Timestamp:
Jan 20, 2023 9:16:34 AM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155324
Message:

IPRT/vcc: Split out the stack probing code (_chkstk) from stack-vcc.asm. bugref:10348 bugref:10261

Location:
trunk/src/VBox/Runtime/common/compiler/vcc
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/compiler/vcc/stack-probe-vcc.asm

    r98142 r98151  
    4747%include "iprt/asmdefs.mac"
    4848%include "iprt/x86.mac"
    49 %ifdef RT_ARCH_AMD64
    50  %include "iprt/win/context-amd64.mac"
    51 %else
    52  %include "iprt/win/context-x86.mac"
    53 %endif
    54 
    55 
    56 ;*********************************************************************************************************************************
    57 ;*      Structures and Typedefs                                                                                                  *
    58 ;*********************************************************************************************************************************
    59 
    60 ;; Variable descriptor.
    61 struc RTC_VAR_DESC_T
    62         .offFrame               resd 1
    63         .cbVar                  resd 1
    64         alignb                  RTCCPTR_CB
    65         .pszName                RTCCPTR_RES 1
    66 endstruc
    67 
    68 ;; Frame descriptor.
    69 struc RTC_FRAME_DESC_T
    70         .cVars                  resd 1
    71         alignb                  RTCCPTR_CB
    72         .paVars                 RTCCPTR_RES 1   ; Array of RTC_VAR_DESC_T.
    73 endstruc
    74 
    75 ;; An alloca allocation.
    76 struc RTC_ALLOCA_ENTRY_T
    77         .uGuard1                resd 1
    78         .pNext                  RTCCPTR_RES 1   ; Misaligned.
    79 %if ARCH_BITS == 32
    80         .pNextPad               resd 1
    81 %endif
    82         .cb                     RTCCPTR_RES 1   ; Misaligned.
    83 %if ARCH_BITS == 32
    84         .cbPad                  resd 1
    85 %endif
    86         .auGuard2               resd 3
    87 endstruc
    88 
    89 %ifdef RT_ARCH_X86
    90  %define FASTCALL_NAME(a_Name, a_cbArgs)        $@ %+ a_Name %+ @ %+ a_cbArgs
    91 %else
    92  %define FASTCALL_NAME(a_Name, a_cbArgs)        NAME(a_Name)
    93 %endif
    94 
    95 
    96 ;*********************************************************************************************************************************
    97 ;*      Defined Constants And Macros                                                                                             *
    98 ;*********************************************************************************************************************************
    99 %define VARIABLE_MARKER_PRE     0xcccccccc
    100 %define VARIABLE_MARKER_POST    0xcccccccc
    101 
    102 %define ALLOCA_FILLER_BYTE      0xcc
    103 %define ALLOCA_FILLER_32        0xcccccccc
    104 
    105 
    106 ;*********************************************************************************************************************************
    107 ;*  Global Variables                                                                                                             *
    108 ;*********************************************************************************************************************************
    109 BEGINDATA
    110 GLOBALNAME __security_cookie
    111         dd  0xdeadbeef
    112         dd  0x0c00ffe0
    113 
    114 
    115 ;*********************************************************************************************************************************
    116 ;*  External Symbols                                                                                                             *
    117 ;*********************************************************************************************************************************
    118 BEGINCODE
    119 extern NAME(rtVccStackVarCorrupted)
    120 extern NAME(rtVccSecurityCookieMismatch)
    121 extern NAME(rtVccRangeCheckFailed)
    122 %ifdef RT_ARCH_X86
    123 extern NAME(rtVccCheckEspFailed)
    124 %endif
    125 
    12649
    12750
     
    233156%endif ; RT_ARCH_X86
    234157
    235 
    236 ;;
    237 ; This just initializes a global and calls _RTC_SetErrorFuncW to NULL, and
    238 ; since we don't have either of those we have nothing to do here.
    239 BEGINPROC _RTC_InitBase
    240         SEH64_END_PROLOGUE
    241         ret
    242 ENDPROC   _RTC_InitBase
    243 
    244 
    245 ;;
    246 ; Nothing to do here.
    247 BEGINPROC _RTC_Shutdown
    248         SEH64_END_PROLOGUE
    249         ret
    250 ENDPROC   _RTC_Shutdown
    251 
    252 
    253 
    254 
    255 ;;
    256 ; Checks stack variable markers.
    257 ;
    258 ; This seems to be a regular C function in the CRT, but x86 is conveniently
    259 ; using the fastcall convention which makes it very similar to amd64.
    260 ;
    261 ; We try make this as sleek as possible, leaving all the trouble for when we
    262 ; find a corrupted stack variable and need to call a C function to complain.
    263 ;
    264 ; @param        pStackFrame     The caller RSP/ESP.  [RCX/ECX]
    265 ; @param        pFrameDesc      Frame descriptor.    [RDX/EDX]
    266 ;
    267 ALIGNCODE(64)
    268 BEGINPROC_RAW   FASTCALL_NAME(_RTC_CheckStackVars, 8)
    269         push    xBP
    270         SEH64_PUSH_xBP
    271         SEH64_END_PROLOGUE
    272 
    273         ;
    274         ; Load the variable count into eax and check that it's not zero.
    275         ;
    276         mov     eax, [xDX + RTC_FRAME_DESC_T.cVars]
    277         test    eax, eax
    278         jz      .return
    279 
    280         ;
    281         ; Make edx/rdx point to the current variable and xBP be the frame pointer.
    282         ; The latter frees up xCX for scratch use and incidentally make stack access
    283         ; go via SS instead of DS (mostly irrlevant in 64-bit and 32-bit mode).
    284         ;
    285         mov     xDX, [xDX + RTC_FRAME_DESC_T.paVars]
    286         mov     xBP, xCX
    287 
    288         ;
    289         ; Loop thru the variables and check that their markers/fences haven't be
    290         ; trampled over.
    291         ;
    292 .next_var:
    293         ; Marker before the variable.
    294 %if ARCH_BITS == 64
    295         movsxd  rcx, dword [xDX + RTC_VAR_DESC_T.offFrame]
    296 %else
    297         mov     xCX, dword [xDX + RTC_VAR_DESC_T.offFrame]
    298 %endif
    299         cmp     dword [xBP + xCX - 4], VARIABLE_MARKER_PRE
    300         jne     rtVccCheckStackVarsFailed
    301 
    302         ; Marker after the variable.
    303         add     ecx, dword [xDX + RTC_VAR_DESC_T.cbVar]
    304 %if ARCH_BITS == 64
    305         movsxd  rcx, ecx
    306 %endif
    307         cmp     dword [xBP + xCX], VARIABLE_MARKER_POST
    308         jne     rtVccCheckStackVarsFailed
    309 
    310         ;
    311         ; Advance to the next variable.
    312         ;
    313 .advance:
    314         add     xDX, RTC_VAR_DESC_T_size
    315         dec     eax
    316         jnz     .next_var
    317 
    318         ;
    319         ; Return.
    320         ;
    321 .return:
    322         pop     xBP
    323         ret
    324 ENDPROC_RAW     FASTCALL_NAME(_RTC_CheckStackVars, 8)
    325 
    326 ;
    327 ; Sub-function for _RTC_CheckStackVars, for purposes of SEH64 unwinding.
    328 ;
    329 ; Note! While we consider this fatal and will terminate the application, the
    330 ;       compiler guys do not seem to think it is all that horrible and will
    331 ;       report failure, maybe do an int3, and then try continue execution.
    332 ;
    333 BEGINPROC_RAW   rtVccCheckStackVarsFailed
    334         nop     ;push    xBP - done in parent function
    335         SEH64_PUSH_xBP
    336         mov     xCX, xBP                    ; xCX = caller pStackFrame. xBP free to become frame pointer.
    337         mov     xBP, xSP
    338         SEH64_SET_FRAME_xBP 0
    339         pushf
    340         push    xAX
    341         SEH64_PUSH_GREG xAX
    342         sub     xSP, CONTEXT_SIZE + 20h
    343         SEH64_ALLOCATE_STACK (CONTEXT_SIZE + 20h)
    344         SEH64_END_PROLOGUE
    345 
    346         lea     xAX, [xBP - CONTEXT_SIZE]
    347         call    NAME(rtVccCaptureContext)
    348 
    349         ; rtVccStackVarCorrupted(uint8_t *pbFrame, RTC_VAR_DESC_T const *pVar, PCONTEXT)
    350 .again:
    351 %ifdef RT_ARCH_AMD64
    352         lea     r8, [xBP - CONTEXT_SIZE]
    353 %else
    354         lea     xAX, [xBP - CONTEXT_SIZE]
    355         mov     [xSP + 8], xAX
    356         mov     [xSP + 4], xDX
    357         mov     [xSP], xCX
    358 %endif
    359         call    NAME(rtVccStackVarCorrupted)
    360         jmp     .again
    361 ENDPROC_RAW     rtVccCheckStackVarsFailed
    362 
    363 
    364 %ifdef RT_ARCH_X86
    365 ;;
    366 ; Called to follow up on a 'CMP ESP, EBP' kind of instruction,
    367 ; expected to report failure if the compare failed.
    368 ;
    369 ; Note! While we consider this fatal and will terminate the application, the
    370 ;       compiler guys do not seem to think it is all that horrible and will
    371 ;       report failure, maybe do an int3, and then try continue execution.
    372 ;
    373 ALIGNCODE(16)
    374 BEGINPROC _RTC_CheckEsp
    375         jne     .unexpected_esp
    376         ret
    377 
    378 .unexpected_esp:
    379         push    xBP
    380         SEH64_PUSH_xBP
    381         mov     xBP, xSP
    382         SEH64_SET_FRAME_xBP 0
    383         pushf
    384         push    xAX
    385         SEH64_PUSH_GREG xAX
    386         sub     xSP, CONTEXT_SIZE + 20h
    387         SEH64_ALLOCATE_STACK (CONTEXT_SIZE + 20h)
    388         SEH64_END_PROLOGUE
    389 
    390         lea     xAX, [xBP - CONTEXT_SIZE]
    391         call    NAME(rtVccCaptureContext)
    392 
    393         ; rtVccCheckEspFailed(PCONTEXT)
    394 .again:
    395         lea     xAX, [xBP - CONTEXT_SIZE]
    396 %ifdef RT_ARCH_AMD64
    397         mov     xCX, xAX
    398 %else
    399         mov     [xSP], xAX
    400 %endif
    401         call    NAME(rtVccCheckEspFailed)
    402         jmp     .again
    403 
    404 ENDPROC   _RTC_CheckEsp
    405 %endif ; RT_ARCH_X86
    406 
    407 
    408 
    409 ;;
    410 ; Initialize an alloca allocation list entry and add it to it.
    411 ;
    412 ; When this is call, presumably _RTC_CheckStackVars2 is used to verify the frame.
    413 ;
    414 ; @param        pNewEntry       Pointer to the new entry.               [RCX/ECX]
    415 ; @param        cbEntry         The entry size, including header.       [RDX/EDX]
    416 ; @param        ppHead          Pointer to the list head pointer.       [R8/stack]
    417 ;
    418 ALIGNCODE(64)
    419 BEGINPROC_RAW   FASTCALL_NAME(_RTC_AllocaHelper, 12)
    420         SEH64_END_PROLOGUE
    421 
    422         ;
    423         ; Check that input isn't NULL or the size isn't zero.
    424         ;
    425         test    xCX, xCX
    426         jz      .return
    427         test    xDX, xDX
    428         jz      .return
    429 %if ARCH_BITS == 64
    430         test    r8, r8
    431 %else
    432         cmp     dword [xSP + xCB], 0
    433 %endif
    434         jz      .return
    435 
    436         ;
    437         ; Memset the memory to ALLOCA_FILLER
    438         ;
    439 %if ARCH_BITS == 64
    440         mov     r10, rdi                ; save rdi
    441         mov     r11, rcx                ; save pNewEntry
    442 %else
    443         push    xDI
    444         push    xCX
    445         cld                             ; paranoia
    446 %endif
    447 
    448         mov     al, ALLOCA_FILLER_BYTE
    449         mov     xDI, xCX                ; entry pointer
    450         mov     xCX, xDX                ; entry size (in bytes)
    451         rep stosb
    452 
    453 %if ARCH_BITS == 64
    454         mov     rdi, r10
    455 %else
    456         pop     xCX
    457         pop     xDI
    458 %endif
    459 
    460         ;
    461         ; Fill in the entry and link it as onto the head of the chain.
    462         ;
    463 %if ARCH_BITS == 64
    464         mov     [r11 + RTC_ALLOCA_ENTRY_T.cb], xDX
    465         mov     xAX, [r8]
    466         mov     [r11 + RTC_ALLOCA_ENTRY_T.pNext], xAX
    467         mov     [r8], r11
    468 %else
    469         mov     [xCX + RTC_ALLOCA_ENTRY_T.cb], xDX
    470         mov     xAX, [xSP + xCB]        ; ppHead
    471         mov     xDX, [xAX]
    472         mov     [xCX + RTC_ALLOCA_ENTRY_T.pNext], xDX
    473         mov     [xAX], xCX
    474 %endif
    475 
    476 .return:
    477 %if ARCH_BITS == 64
    478         ret
    479 %else
    480         ret     4
    481 %endif
    482 ENDPROC_RAW     FASTCALL_NAME(_RTC_AllocaHelper, 12)
    483 
    484 
    485 ;;
    486 ; Checks if the security cookie ok, complaining and terminating if it isn't.
    487 ;
    488 ALIGNCODE(16)
    489 BEGINPROC_RAW   FASTCALL_NAME(__security_check_cookie, 4)
    490         SEH64_END_PROLOGUE
    491         cmp     xCX, [NAME(__security_cookie) xWrtRIP]
    492         jne     rtVccSecurityCookieFailed
    493         ;; amd64 version checks if the top 16 bits are zero, we skip that for now.
    494         ret
    495 ENDPROC_RAW     FASTCALL_NAME(__security_check_cookie, 4)
    496 
    497 ; Sub-function for __security_check_cookie, for purposes of SEH64 unwinding.
    498 BEGINPROC_RAW   rtVccSecurityCookieFailed
    499         push    xBP
    500         SEH64_PUSH_xBP
    501         mov     xBP, xSP
    502         SEH64_SET_FRAME_xBP 0
    503         pushf
    504         push    xAX
    505         SEH64_PUSH_GREG xAX
    506         sub     xSP, CONTEXT_SIZE + 20h
    507         SEH64_ALLOCATE_STACK (CONTEXT_SIZE + 20h)
    508         SEH64_END_PROLOGUE
    509 
    510         lea     xAX, [xBP - CONTEXT_SIZE]
    511         call    NAME(rtVccCaptureContext)
    512 
    513         ; rtVccSecurityCookieMismatch(uCookie, PCONTEXT)
    514 .again:
    515 %ifdef RT_ARCH_AMD64
    516         lea     xDX, [xBP - CONTEXT_SIZE]
    517 %else
    518         lea     xAX, [xBP - CONTEXT_SIZE]
    519         mov     [xSP + 4], xAX
    520         mov     [xSP], xCX
    521 %endif
    522         call    NAME(rtVccSecurityCookieMismatch)
    523         jmp     .again
    524 ENDPROC_RAW     rtVccSecurityCookieFailed
    525 
    526 
    527 ;;
    528 ; Generated when using /GS - buffer security checks - so, fatal.
    529 ;
    530 ; Doesn't seem to take any parameters.
    531 ;
    532 BEGINPROC __report_rangecheckfailure
    533         push    xBP
    534         SEH64_PUSH_xBP
    535         mov     xBP, xSP
    536         SEH64_SET_FRAME_xBP 0
    537         pushf
    538         push    xAX
    539         SEH64_PUSH_GREG xAX
    540         sub     xSP, CONTEXT_SIZE + 20h
    541         SEH64_ALLOCATE_STACK (CONTEXT_SIZE + 20h)
    542         SEH64_END_PROLOGUE
    543 
    544         lea     xAX, [xBP - CONTEXT_SIZE]
    545         call    NAME(rtVccCaptureContext)
    546 
    547         ; rtVccRangeCheckFailed(PCONTEXT)
    548 .again:
    549         lea     xAX, [xBP - CONTEXT_SIZE]
    550 %ifdef RT_ARCH_AMD64
    551         mov     xCX, xAX
    552 %else
    553         mov     [xSP], xAX
    554 %endif
    555         call    NAME(rtVccRangeCheckFailed)
    556         jmp     .again
    557 ENDPROC   __report_rangecheckfailure
    558 
    559 
    560 %if 0 ; Currently not treating these as completely fatal, just like the
    561       ; compiler guys do.  I'm sure the compiler only generate these calls
    562       ; if it thinks a variable could be used uninitialized, however I'm not
    563       ; really sure if there is a runtime check in addition or if it's an
    564       ; action that always will be taken in a code path deemed to be bad.
    565       ; Judging from the warnings, the compile time analysis leave lots to be
    566       ; desired (lots of false positives).
    567 ;;
    568 ; Not entirely sure how and when the compiler generates these.
    569 ; extern "C" void __cdecl _RTC_UninitUse(const char *pszVar)
    570 BEGINPROC   _RTC_UninitUse
    571         push    xBP
    572         SEH64_PUSH_xBP
    573         mov     xBP, xSP
    574         SEH64_SET_FRAME_xBP 0
    575         pushf
    576         push    xAX
    577         SEH64_PUSH_GREG xAX
    578         sub     xSP, CONTEXT_SIZE + 20h
    579         SEH64_ALLOCATE_STACK (CONTEXT_SIZE + 20h)
    580         SEH64_END_PROLOGUE
    581 
    582         lea     xAX, [xBP - CONTEXT_SIZE]
    583         call    NAME(rtVccCaptureContext)
    584 
    585         extern NAME(rtVccUninitializedVariableUse)
    586         ; rtVccUninitializedVariableUse(const char *pszVar, PCONTEXT)
    587 .again:
    588 %ifdef RT_ARCH_AMD64
    589         lea     xDX, [xBP - CONTEXT_SIZE]
    590 %else
    591         lea     xAX, [xBP - CONTEXT_SIZE]
    592         mov     [xSP + xCB], xAX
    593         mov     xAX, [xBP + xCB * 2]
    594         mov     [xSP], xAX
    595 %endif
    596         call    NAME(rtVccUninitializedVariableUse)
    597         jmp     .again
    598 ENDPROC     _RTC_UninitUse
    599 %endif
    600 
    601 ;;
    602 ; Internal worker that creates a CONTEXT record for the caller.
    603 ;
    604 ; This expects a old-style stack frame setup, with xBP as base, such that:
    605 ;       xBP+xCB*1:  Return address  -> Rip/Eip
    606 ;       xBP+xCB*0:  Return xBP      -> Rbp/Ebp
    607 ;       xBP-xCB*1:  EFLAGS          -> EFlags
    608 ;       xBP-xCB*2:  Saved xAX       -> Rax/Eax
    609 ;
    610 ; @param    pCtx        xAX     Pointer to a CONTEXT structure.
    611 ;
    612 BEGINPROC rtVccCaptureContext
    613         SEH64_END_PROLOGUE
    614 
    615 %ifdef RT_ARCH_AMD64
    616         mov     [xAX + CONTEXT.Rcx], rcx
    617         mov     [xAX + CONTEXT.Rdx], rdx
    618         mov     rcx, [xBP - xCB*2]
    619         mov     [xAX + CONTEXT.Rax], ecx
    620         mov     [xAX + CONTEXT.Rbx], rbx
    621         lea     rcx, [xBP + xCB*2]
    622         mov     [xAX + CONTEXT.Rsp], rcx
    623         mov     rdx, [xBP]
    624         mov     [xAX + CONTEXT.Rbp], rdx
    625         mov     [xAX + CONTEXT.Rdi], rdi
    626         mov     [xAX + CONTEXT.Rsi], rsi
    627         mov     [xAX + CONTEXT.R8], r8
    628         mov     [xAX + CONTEXT.R9], r9
    629         mov     [xAX + CONTEXT.R10], r10
    630         mov     [xAX + CONTEXT.R11], r11
    631         mov     [xAX + CONTEXT.R12], r12
    632         mov     [xAX + CONTEXT.R13], r13
    633         mov     [xAX + CONTEXT.R14], r14
    634         mov     [xAX + CONTEXT.R15], r15
    635 
    636         mov     rcx, [xBP + xCB*1]
    637         mov     [xAX + CONTEXT.Rip], rcx
    638         mov     edx, [xBP - xCB*1]
    639         mov     [xAX + CONTEXT.EFlags], edx
    640 
    641         mov     dx, ss
    642         mov     [xAX + CONTEXT.SegSs], dx
    643         mov     cx, cs
    644         mov     [xAX + CONTEXT.SegCs], cx
    645         mov     dx, ds
    646         mov     [xAX + CONTEXT.SegDs], dx
    647         mov     cx, es
    648         mov     [xAX + CONTEXT.SegEs], cx
    649         mov     dx, fs
    650         mov     [xAX + CONTEXT.SegFs], dx
    651         mov     cx, gs
    652         mov     [xAX + CONTEXT.SegGs], cx
    653 
    654         mov     dword [xAX + CONTEXT.ContextFlags], CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS
    655 
    656         ; Clear stuff we didn't set.
    657         xor     edx, edx
    658         mov     [xAX + CONTEXT.P1Home], rdx
    659         mov     [xAX + CONTEXT.P2Home], rdx
    660         mov     [xAX + CONTEXT.P3Home], rdx
    661         mov     [xAX + CONTEXT.P4Home], rdx
    662         mov     [xAX + CONTEXT.P5Home], rdx
    663         mov     [xAX + CONTEXT.P6Home], rdx
    664         mov     [xAX + CONTEXT.MxCsr], edx
    665         mov     [xAX + CONTEXT.Dr0], rdx
    666         mov     [xAX + CONTEXT.Dr1], rdx
    667         mov     [xAX + CONTEXT.Dr2], rdx
    668         mov     [xAX + CONTEXT.Dr3], rdx
    669         mov     [xAX + CONTEXT.Dr6], rdx
    670         mov     [xAX + CONTEXT.Dr7], rdx
    671 
    672         mov     ecx, CONTEXT_size - CONTEXT.FltSave
    673         AssertCompile(((CONTEXT_size - CONTEXT.FltSave) % 8) == 0)
    674 .again:
    675         mov     [xAX + CONTEXT.FltSave + xCX - 8], rdx
    676         sub     ecx, 8
    677         jnz     .again
    678 
    679         ; Restore edx and ecx.
    680         mov     rcx, [xAX + CONTEXT.Rcx]
    681         mov     rdx, [xAX + CONTEXT.Rdx]
    682 
    683 %elifdef RT_ARCH_X86
    684 
    685         mov     [xAX + CONTEXT.Ecx], ecx
    686         mov     [xAX + CONTEXT.Edx], edx
    687         mov     ecx, [xBP - xCB*2]
    688         mov     [xAX + CONTEXT.Eax], ecx
    689         mov     [xAX + CONTEXT.Ebx], ebx
    690         lea     ecx, [xBP + xCB*2]
    691         mov     [xAX + CONTEXT.Esp], ecx
    692         mov     edx, [xBP]
    693         mov     [xAX + CONTEXT.Ebp], edx
    694         mov     [xAX + CONTEXT.Edi], edi
    695         mov     [xAX + CONTEXT.Esi], esi
    696 
    697         mov     ecx, [xBP + xCB]
    698         mov     [xAX + CONTEXT.Eip], ecx
    699         mov     ecx, [xBP - xCB*1]
    700         mov     [xAX + CONTEXT.EFlags], ecx
    701 
    702         mov     dx, ss
    703         movzx   edx, dx
    704         mov     [xAX + CONTEXT.SegSs], edx
    705         mov     cx, cs
    706         movzx   ecx, cx
    707         mov     [xAX + CONTEXT.SegCs], ecx
    708         mov     dx, ds
    709         movzx   edx, dx
    710         mov     [xAX + CONTEXT.SegDs], edx
    711         mov     cx, es
    712         movzx   ecx, cx
    713         mov     [xAX + CONTEXT.SegEs], ecx
    714         mov     dx, fs
    715         movzx   edx, dx
    716         mov     [xAX + CONTEXT.SegFs], edx
    717         mov     cx, gs
    718         movzx   ecx, cx
    719         mov     [xAX + CONTEXT.SegGs], ecx
    720 
    721         mov     dword [xAX + CONTEXT.ContextFlags], CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS
    722 
    723         ; Clear stuff we didn't set.
    724         xor     edx, edx
    725         mov     [xAX + CONTEXT.Dr0], edx
    726         mov     [xAX + CONTEXT.Dr1], edx
    727         mov     [xAX + CONTEXT.Dr2], edx
    728         mov     [xAX + CONTEXT.Dr3], edx
    729         mov     [xAX + CONTEXT.Dr6], edx
    730         mov     [xAX + CONTEXT.Dr7], edx
    731 
    732         mov     ecx, CONTEXT_size - CONTEXT.ExtendedRegisters
    733 .again:
    734         mov     [xAX + CONTEXT.ExtendedRegisters + xCX - 4], edx
    735         sub     ecx, 4
    736         jnz     .again
    737 
    738         ; Restore edx and ecx.
    739         mov     ecx, [xAX + CONTEXT.Ecx]
    740         mov     edx, [xAX + CONTEXT.Edx]
    741 
    742 %else
    743  %error RT_ARCH
    744 %endif
    745         ret
    746 ENDPROC   rtVccCaptureContext
    747 
  • trunk/src/VBox/Runtime/common/compiler/vcc/stack-vcc.asm

    r98103 r98151  
    124124%endif
    125125
    126 
    127 
    128 ;;
    129 ; Probe stack to trigger guard faults, and for x86 to allocate stack space.
    130 ;
    131 ; @param    xAX     Frame size.
    132 ; @uses     AMD64:  Probably nothing. EAX is certainly not supposed to change.
    133 ;           x86:    ESP = ESP - EAX; EFLAGS, nothing else
    134 ;
    135 ALIGNCODE(64)
    136 GLOBALNAME_RAW  __alloca_probe, __alloca_probe, function
    137 BEGINPROC_RAW   __chkstk
    138         push    xBP
    139         SEH64_PUSH_xBP
    140         mov     xBP, xSP
    141         SEH64_SET_FRAME_xBP 0
    142         push    xAX
    143         SEH64_PUSH_GREG xAX
    144         push    xBX
    145         SEH64_PUSH_GREG xBX
    146         SEH64_END_PROLOGUE
    147 
    148         ;
    149         ; Adjust eax so we're relative to [xBP - xCB*2].
    150         ;
    151         sub     xAX, xCB * 4
    152         jle     .touch_loop_done            ; jump if rax < xCB*4, very unlikely
    153 
    154         ;
    155         ; Subtract what's left of the current page from eax and only engage
    156         ; the touch loop if (int)xAX > 0.
    157         ;
    158         lea     ebx, [ebp - xCB * 2]
    159         and     ebx, PAGE_SIZE - 1
    160         sub     xAX, xBX
    161         jnl     .touch_loop                 ; jump if pages to touch.
    162 
    163 .touch_loop_done:
    164         pop     xBX
    165         pop     xAX
    166         leave
    167 %ifndef RT_ARCH_X86
    168         ret
    169 %else
    170         ;
    171         ; Do the stack space allocation and jump to the return location.
    172         ;
    173         sub     esp, eax
    174         add     esp, 4
    175         jmp     dword [esp + eax - 4]
    176 %endif
    177 
    178         ;
    179         ; The touch loop.
    180         ;
    181 .touch_loop:
    182         sub     xBX, PAGE_SIZE
    183 %if 1
    184         mov     [xBP + xBX - xCB * 2], bl
    185 %else
    186         or      byte [xBP + xBX - xCB * 2], 0   ; non-destructive variant...
    187 %endif
    188         sub     xAX, PAGE_SIZE
    189         jnl     .touch_loop
    190         jmp     .touch_loop_done
    191 ENDPROC_RAW     __chkstk
    192 
    193 
    194 %ifdef RT_ARCH_X86
    195 ;;
    196 ; 8 and 16 byte aligned alloca w/ probing.
    197 ;
    198 ; This routine adjusts the allocation size so __chkstk will return a
    199 ; correctly aligned allocation.
    200 ;
    201 ; @param    xAX     Unaligned allocation size.
    202 ;
    203 %macro __alloc_probe_xxx 1
    204 ALIGNCODE(16)
    205 BEGINPROC_RAW   __alloca_probe_ %+ %1
    206         push    ecx
    207 
    208         ;
    209         ; Calc the ESP address after the allocation and adjust EAX so that it
    210         ; will be aligned as desired.
    211         ;
    212         lea     ecx, [esp + 8]
    213         sub     ecx, eax
    214         and     ecx, %1 - 1
    215         add     eax, ecx
    216         jc      .bad_alloc_size
    217 .continue:
    218 
    219         pop     ecx
    220         jmp     __alloca_probe
    221 
    222 .bad_alloc_size:
    223   %ifdef RT_STRICT
    224         int3
    225   %endif
    226         or      eax, 0xfffffff0
    227         jmp     .continue
    228 ENDPROC_RAW     __alloca_probe_ %+ %1
    229 %endmacro
    230 
    231 __alloc_probe_xxx 16
    232 __alloc_probe_xxx 8
    233 %endif ; RT_ARCH_X86
    234126
    235127
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