Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/toolkit/crashreporter/test/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  win64UnwindInfoTests.asm   Sprache: Masm

 
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.

; Comments indicate stack memory layout during execution.
; For example at the top of a function, where RIP just points to the return
; address, the stack looks like
; rip = [ra]
; And after pushing rax to the stack,
; rip = [rax][ra]
; And then, after allocating 20h bytes on the stack,
; rip = [..20..][rax][ra]
; And then, after pushing a function pointer,
; rip = [pfn][..20..][rax][ra]

include ksamd64.inc

.code

; It helps to add padding between functions so they're not right up against
; each other. Adds clarity to debugging, and gives a bit of leeway when
; searching for symbols (e.g. a function whose last instruction is CALL
; would push a return address that's in the next function.)
PaddingBetweenFunctions macro
  repeat 10h
     int 3
  endm
endm

DoCrash macro
  mov rax, 7
  mov byte ptr [rax], 9
endm

PaddingBetweenFunctions

; There is no rip addressing mode in x64. The only way to get the value
; of rip is to call a function, and pop it from the stack.
WhoCalledMe proc
  pop rax ; rax is now ra
  push rax ; Restore ra so this function can return.
  sub rax, 5 ; Correct for the size of the call instruction
  ret
WhoCalledMe endp

PaddingBetweenFunctions

; Any function that we expect to test against on the stack, we'll need its
; real address. If we use function pointers in C, we'll get the address to jump
; table entries. This bit of code at the beginning of each function will
; return the real address we'd expect to see in stack traces.
;
; rcx (1st arg) = mode
; rax (return)  = address of either NO_MANS_LAND or this function.
;
; When mode is 0, we place the address of NO_MANS_LAND in RAX, for the function
; to use as it wants. This is just for convenience because almost all functions
; here need this address at some point.
;
; When mode is 1, the address of this function is returned.
TestHeader macro
  call WhoCalledMe
  test rcx, rcx
  je continue_test
  ret
continue_test:
  inc rcx
  call x64CrashCFITest_NO_MANS_LAND
  xor rcx, rcx
endm

; The point of this is to add a stack frame to test against.
; void* x64CrashCFITest_Launcher(int getAddress, void* pTestFn)
x64CrashCFITest_Launcher proc frame
  TestHeader

  .endprolog
  call rdx
  ret
x64CrashCFITest_Launcher endp

PaddingBetweenFunctions

; void* x64CrashCFITest_NO_MANS_LAND(uint64_t mode);
; Not meant to be called. Only when mode = 1 in order to return its address.
; Place this function's address on the stack so the stack scanning algorithm
; thinks this is a return address, and places it on the stack trace.
x64CrashCFITest_NO_MANS_LAND proc frame
  TestHeader
  .endprolog
  ret
x64CrashCFITest_NO_MANS_LAND endp

PaddingBetweenFunctions

; Test that we:
; - handle unknown opcodes gracefully
; - fall back to other stack unwind strategies if CFI doesn't work
;
; In order to properly unwind this frame, we'd need to fully support
; SET_FPREG with offsets, plus restoring registers via PUSH_NONVOL.
; To do this, sprinkle the stack with bad return addresses
; and stack pointers.
x64CrashCFITest_UnknownOpcode proc frame
  TestHeader

  push rax
  .allocstack 8

  push rbp
  .pushreg rbp

  push rax
  push rsp
  push rax
  push rsp
  .allocstack 20h
  ; rsp = [rsp][pfn][rsp][pfn][rbp][pfn][ra]

  lea rbp, [rsp+10h]
  .setframe rbp, 10h
  ; rsp = [rsp][pfn] [rsp][pfn][rbp][pfn][ra]
  ; rbp =           ^

  .endprolog

  ; Now modify RSP so measuring stack size from unwind ops will not help
  ; finding the return address.
  push rax
  push rsp
  ; rsp = [rsp][pfn][rsp][pfn] [rsp][pfn][rbp][pfn][ra]

  DoCrash

x64CrashCFITest_UnknownOpcode endp

PaddingBetweenFunctions

; void* x64CrashCFITest_PUSH_NONVOL(uint64_t mode);
;
; Test correct handling of PUSH_NONVOL unwind code.
;
x64CrashCFITest_PUSH_NONVOL proc frame
  TestHeader

  push r10
  .pushreg r10
  push r15
  .pushreg r15
  push rbx
  .pushreg rbx
  push rsi
  .pushreg rsi
  push rbp
  .pushreg rbp
  ; rsp = [rbp][rsi][rbx][r15][r10][ra]

  push rax
  .allocstack 8
  ; rsp = [pfn][rbp][rsi][rbx][r15][r10][ra]

  .endprolog

  DoCrash

x64CrashCFITest_PUSH_NONVOL endp

PaddingBetweenFunctions

; void* x64CrashCFITest_ALLOC_SMALL(uint64_t mode);
;
; Small allocations are between 8bytes and 512kb-8bytes
;
x64CrashCFITest_ALLOC_SMALL proc frame
  TestHeader

  push rax
  push rax
  push rax
  push rax
  .allocstack 20h
  ; rsp = [pfn][pfn][pfn][pfn][ra]

  .endprolog

  DoCrash

x64CrashCFITest_ALLOC_SMALL endp

PaddingBetweenFunctions

; void* x64CrashCFITest_ALLOC_LARGE(uint64_t mode);
;
; Allocations between 512kb and 4gb
; Note: ReserveStackSpace() in nsTestCrasher.cpp pre-allocates stack
; space for this.
x64CrashCFITest_ALLOC_LARGE proc frame
  TestHeader

  sub rsp, 0a000h
  .allocstack 0a000h
  ; rsp = [..640kb..][ra]

  mov qword ptr [rsp], rax
  ; rsp = [pfn][..640kb-8..][ra]

  .endprolog

  DoCrash

x64CrashCFITest_ALLOC_LARGE endp

PaddingBetweenFunctions

; void* x64CrashCFITest_SAVE_NONVOL(uint64_t mode);
;
; Test correct handling of SAVE_NONVOL unwind code.
;
x64CrashCFITest_SAVE_NONVOL proc frame
  TestHeader

  sub rsp, 30h
  .allocstack 30h
  ; rsp = [..30..][ra]

  mov qword ptr [rsp+28h], r10
  .savereg r10, 28h
  mov qword ptr [rsp+20h], rbp
  .savereg rbp, 20h
  mov qword ptr [rsp+18h], rsi
  .savereg rsi, 18h
  mov qword ptr [rsp+10h], rbx
  .savereg rbx, 10h
  mov qword ptr [rsp+8], r15
  .savereg r15, 8
  ; rsp = [r15][rbx][rsi][rbp][r10][ra]

  mov qword ptr [rsp], rax

  ; rsp = [pfn][r15][rbx][rsi][rbp][r10][ra]

  .endprolog

  DoCrash

x64CrashCFITest_SAVE_NONVOL endp

PaddingBetweenFunctions

; void* x64CrashCFITest_SAVE_NONVOL_FAR(uint64_t mode);
;
; Similar to the test above but adding 640kb to most offsets.
; Note: ReserveStackSpace() in nsTestCrasher.cpp pre-allocates stack
; space for this.
x64CrashCFITest_SAVE_NONVOL_FAR proc frame
  TestHeader

  sub rsp, 0a0030h
  .allocstack 0a0030h
  ; rsp = [..640k..][..30..][ra]

  mov qword ptr [rsp+28h+0a0000h], r10
  .savereg r10, 28h+0a0000h
  mov qword ptr [rsp+20h+0a0000h], rbp
  .savereg rbp, 20h+0a0000h
  mov qword ptr [rsp+18h+0a0000h], rsi
  .savereg rsi, 18h+0a0000h
  mov qword ptr [rsp+10h+0a0000h], rbx
  .savereg rbx, 10h+0a0000h
  mov qword ptr [rsp+8+0a0000h], r15
  .savereg r15, 8+0a0000h
  ; rsp = [..640k..][..8..][r15][rbx][rsi][rbp][r10][ra]

  mov qword ptr [rsp], rax

  ; rsp = [pfn][..640k..][r15][rbx][rsi][rbp][r10][ra]

  .endprolog

  DoCrash

x64CrashCFITest_SAVE_NONVOL_FAR endp

PaddingBetweenFunctions

; void* x64CrashCFITest_SAVE_XMM128(uint64_t mode);
;
; Test correct handling of SAVE_XMM128 unwind code.
x64CrashCFITest_SAVE_XMM128 proc frame
  TestHeader

  sub rsp, 30h
  .allocstack 30h
  ; rsp = [..30..][ra]

  movdqu [rsp+20h], xmm6
  .savexmm128 xmm6, 20h
  ; rsp = [..20..][xmm6][ra]

  movdqu [rsp+10h], xmm15
  .savexmm128 xmm15, 10h
  ; rsp = [..10..][xmm15][xmm6][ra]

  mov qword ptr [rsp], rax
  ; rsp = [pfn][..8..][xmm15][xmm6][ra]

  .endprolog

  DoCrash

x64CrashCFITest_SAVE_XMM128 endp

PaddingBetweenFunctions

; void* x64CrashCFITest_SAVE_XMM128(uint64_t mode);
;
; Similar to the test above but adding 640kb to most offsets.
; Note: ReserveStackSpace() in nsTestCrasher.cpp pre-allocates stack
; space for this.
x64CrashCFITest_SAVE_XMM128_FAR proc frame
  TestHeader

  sub rsp, 0a0030h
  .allocstack 0a0030h
  ; rsp = [..640kb..][..30..][ra]

  movdqu [rsp+20h+0a0000h], xmm6
  .savexmm128 xmm6, 20h+0a0000h
  ; rsp = [..640kb..][..20..][xmm6][ra]

  movdqu [rsp+10h+0a0000h], xmm6
  .savexmm128 xmm15, 10h+0a0000h
  ; rsp = [..640kb..][..10..][xmm15][xmm6][ra]

  mov qword ptr [rsp], rax
  ; rsp = [pfn][..640kb..][..8..][xmm15][xmm6][ra]

  .endprolog

  DoCrash

x64CrashCFITest_SAVE_XMM128_FAR endp

PaddingBetweenFunctions

; void* x64CrashCFITest_EPILOG(uint64_t mode);
;
; The epilog unwind op will also set the unwind version to 2.
; Test that we don't choke on UWOP_EPILOG or version 2 unwind info.
x64CrashCFITest_EPILOG proc frame
  TestHeader

  push rax
  .allocstack 8
  ; rsp = [pfn][ra]

  .endprolog

  DoCrash

  .beginepilog

  ret

x64CrashCFITest_EPILOG endp

PaddingBetweenFunctions

; Having an EOF symbol at the end of this file contains symbolication to this
; file. So addresses beyond this file don't get mistakenly symbolicated as a
; meaningful function name.
x64CrashCFITest_EOF proc frame
  TestHeader
  .endprolog
  ret
x64CrashCFITest_EOF endp

end

Messung V0.5
C=92 H=93 G=92

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.