github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/safecopy/sighandler_amd64.s (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include "textflag.h"
    16  
    17  // The signals handled by sigHandler.
    18  #define SIGBUS  7
    19  #define SIGSEGV 11
    20  
    21  // Offsets to the registers in context->uc_mcontext.gregs[].
    22  #define REG_RDI 0x68
    23  #define REG_RAX 0x90
    24  #define REG_IP  0xa8
    25  
    26  // Offset to the si_addr field of siginfo.
    27  #define SI_CODE 0x08
    28  #define SI_ADDR 0x10
    29  
    30  // signalHandler is the signal handler for SIGSEGV and SIGBUS signals. It must
    31  // not be set up as a handler to any other signals.
    32  //
    33  // If the instruction causing the signal is within a safecopy-protected
    34  // function, the signal is handled such that execution resumes in the
    35  // appropriate fault handling stub with AX containing the faulting address and
    36  // DI containing the signal number. Otherwise control is transferred to the
    37  // previously configured signal handler (savedSigSegvHandler or
    38  // savedSigBusHandler).
    39  //
    40  // This function cannot be written in go because it runs whenever a signal is
    41  // received by the thread (preempting whatever was running), which includes when
    42  // garbage collector has stopped or isn't expecting any interactions (like
    43  // barriers).
    44  //
    45  // The arguments are the following:
    46  // DI - The signal number.
    47  // SI - Pointer to siginfo_t structure.
    48  // DX - Pointer to ucontext structure.
    49  TEXT ·signalHandler(SB),NOSPLIT|NOFRAME,$0
    50  	// Check if the signal is from the kernel.
    51  	MOVQ $0x0, CX
    52  	CMPL CX, SI_CODE(SI)
    53  	JGE original_handler
    54  
    55  	// Check if RIP is within the area we care about.
    56  	MOVQ REG_IP(DX), CX
    57  	CMPQ CX, ·memcpyBegin(SB)
    58  	JB not_memcpy
    59  	CMPQ CX, ·memcpyEnd(SB)
    60  	JAE not_memcpy
    61  
    62  	// Modify the context such that execution will resume in the fault
    63  	// handler.
    64  	LEAQ handleMemcpyFault(SB), CX
    65  	JMP handle_fault
    66  
    67  not_memcpy:
    68  	CMPQ CX, ·memclrBegin(SB)
    69  	JB not_memclr
    70  	CMPQ CX, ·memclrEnd(SB)
    71  	JAE not_memclr
    72  
    73  	LEAQ handleMemclrFault(SB), CX
    74  	JMP handle_fault
    75  
    76  not_memclr:
    77  	CMPQ CX, ·swapUint32Begin(SB)
    78  	JB not_swapuint32
    79  	CMPQ CX, ·swapUint32End(SB)
    80  	JAE not_swapuint32
    81  
    82  	LEAQ handleSwapUint32Fault(SB), CX
    83  	JMP handle_fault
    84  
    85  not_swapuint32:
    86  	CMPQ CX, ·swapUint64Begin(SB)
    87  	JB not_swapuint64
    88  	CMPQ CX, ·swapUint64End(SB)
    89  	JAE not_swapuint64
    90  
    91  	LEAQ handleSwapUint64Fault(SB), CX
    92  	JMP handle_fault
    93  
    94  not_swapuint64:
    95  	CMPQ CX, ·compareAndSwapUint32Begin(SB)
    96  	JB not_casuint32
    97  	CMPQ CX, ·compareAndSwapUint32End(SB)
    98  	JAE not_casuint32
    99  
   100  	LEAQ handleCompareAndSwapUint32Fault(SB), CX
   101  	JMP handle_fault
   102  
   103  not_casuint32:
   104  	CMPQ CX, ·loadUint32Begin(SB)
   105  	JB not_loaduint32
   106  	CMPQ CX, ·loadUint32End(SB)
   107  	JAE not_loaduint32
   108  
   109  	LEAQ handleLoadUint32Fault(SB), CX
   110  	JMP handle_fault
   111  
   112  not_loaduint32:
   113  	CMPQ CX, ·checkXstateBegin(SB)
   114  	JB not_checkXstate
   115  	CMPQ CX, ·checkXstateEnd(SB)
   116  	JAE not_checkXstate
   117  
   118  	LEAQ handleCheckXstateFault(SB), CX
   119  	JMP handle_fault
   120  not_checkXstate:
   121  original_handler:
   122  	// Jump to the previous signal handler, which is likely the golang one.
   123  	XORQ CX, CX
   124  	MOVQ ·savedSigBusHandler(SB), AX
   125  	CMPL DI, $SIGSEGV
   126  	CMOVQEQ ·savedSigSegVHandler(SB), AX
   127  	JMP AX
   128  
   129  handle_fault:
   130  	// Entered with the address of the fault handler in RCX; store it in
   131  	// RIP.
   132  	MOVQ CX, REG_IP(DX)
   133  
   134  	// Store the faulting address in RAX.
   135  	MOVQ SI_ADDR(SI), CX
   136  	MOVQ CX, REG_RAX(DX)
   137  
   138  	// Store the signal number in EDI.
   139  	MOVL DI, REG_RDI(DX)
   140  
   141  	RET
   142  
   143  // func addrOfSignalHandler() uintptr
   144  TEXT ·addrOfSignalHandler(SB), $0-8
   145  	MOVQ	$·signalHandler(SB), AX
   146  	MOVQ	AX, ret+0(FP)
   147  	RET