VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/compiler/vcc/stack-vcc.asm@ 97868

Last change on this file since 97868 was 96573, checked in by vboxsync, 3 years ago

IPRT/nocrt: Fail fast and safer stack corruption. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.3 KB
Line 
1; $Id: stack-vcc.asm 96573 2022-09-02 02:04:12Z vboxsync $
2;; @file
3; IPRT - Stack related Visual C++ support routines.
4;
5
6;
7; Copyright (C) 2022 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.215389.xyz.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37
38
39;*********************************************************************************************************************************
40;* Header Files *
41;*********************************************************************************************************************************
42%if 0 ; YASM's builtin SEH64 support doesn't cope well with code alignment, so use our own.
43 %define RT_ASM_WITH_SEH64
44%else
45 %define RT_ASM_WITH_SEH64_ALT
46%endif
47%include "iprt/asmdefs.mac"
48%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.
61struc RTC_VAR_DESC_T
62 .offFrame resd 1
63 .cbVar resd 1
64 alignb RTCCPTR_CB
65 .pszName RTCCPTR_RES 1
66endstruc
67
68;; Frame descriptor.
69struc RTC_FRAME_DESC_T
70 .cVars resd 1
71 alignb RTCCPTR_CB
72 .paVars RTCCPTR_RES 1 ; Array of RTC_VAR_DESC_T.
73endstruc
74
75;; An alloca allocation.
76struc 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
87endstruc
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;*********************************************************************************************************************************
109BEGINDATA
110GLOBALNAME __security_cookie
111 dd 0xdeadbeef
112 dd 0x0c00ffe0
113
114
115;*********************************************************************************************************************************
116;* External Symbols *
117;*********************************************************************************************************************************
118BEGINCODE
119extern NAME(rtVccStackVarCorrupted)
120extern NAME(rtVccSecurityCookieMismatch)
121extern NAME(rtVccRangeCheckFailed)
122%ifdef RT_ARCH_X86
123extern NAME(rtVccCheckEspFailed)
124%endif
125
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;
135ALIGNCODE(64)
136GLOBALNAME_RAW __alloca_probe, __alloca_probe, function
137BEGINPROC_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
191ENDPROC_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
204ALIGNCODE(16)
205BEGINPROC_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
228ENDPROC_RAW __alloca_probe_ %+ %1
229%endmacro
230
231__alloc_probe_xxx 16
232__alloc_probe_xxx 8
233%endif ; RT_ARCH_X86
234
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.
239BEGINPROC _RTC_InitBase
240 SEH64_END_PROLOGUE
241 ret
242ENDPROC _RTC_InitBase
243
244
245;;
246; Nothing to do here.
247BEGINPROC _RTC_Shutdown
248 SEH64_END_PROLOGUE
249 ret
250ENDPROC _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;
267ALIGNCODE(64)
268BEGINPROC_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
324ENDPROC_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;
333BEGINPROC_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
361ENDPROC_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;
373ALIGNCODE(16)
374BEGINPROC _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
404ENDPROC _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;
418ALIGNCODE(64)
419BEGINPROC_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
482ENDPROC_RAW FASTCALL_NAME(_RTC_AllocaHelper, 12)
483
484
485;;
486; Checks if the security cookie ok, complaining and terminating if it isn't.
487;
488ALIGNCODE(16)
489BEGINPROC_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
495ENDPROC_RAW FASTCALL_NAME(__security_check_cookie, 4)
496
497; Sub-function for __security_check_cookie, for purposes of SEH64 unwinding.
498BEGINPROC_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
524ENDPROC_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;
532BEGINPROC __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
557ENDPROC __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)
570BEGINPROC _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
598ENDPROC _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;
612BEGINPROC 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
746ENDPROC rtVccCaptureContext
747
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette