Print this page
15254 %ymm registers not restored after signal handler
15367 x86 getfpregs() summons corrupting %xmm ghosts
15333 want x86 /proc xregs support (libc_db, libproc, mdb, etc.)
15336 want libc functions for extended ucontext_t
15334 want ps_lwphandle-specific reg routines
15328 FPU_CW_INIT mistreats reserved bit
15335 i86pc fpu_subr.c isn't really platform-specific
15332 setcontext(2) isn't actually noreturn
15331 need <sys/stdalign.h>
Change-Id: I7060aa86042dfb989f77fc3323c065ea2eafa9ad
Conflicts:
    usr/src/uts/common/fs/proc/prcontrol.c
    usr/src/uts/intel/os/archdep.c
    usr/src/uts/intel/sys/ucontext.h
    usr/src/uts/intel/syscall/getcontext.c

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/i386/sys/getcontext.S
          +++ new/usr/src/lib/libc/i386/sys/getcontext.S
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
       27 +/*
       28 + * Copyright 2023 Oxide Computer Company
       29 + */
       30 +
  27   31          .file   "getcontext.s"
  28   32  
  29   33  #include <sys/asm_linkage.h>
  30   34  
  31   35          ANSI_PRAGMA_WEAK(getcontext,function)
  32   36          ANSI_PRAGMA_WEAK(swapcontext,function)
  33   37  
  34   38  #include "SYS.h"
  35   39  #include <assym.h>
  36   40  
  37   41  /*
  38   42   * getcontext() and swapcontext() are written in assembler since it has to
  39   43   * capture the correct machine state of the caller, including
  40   44   * the registers: %edi, %esi and %ebx.
  41   45   *
  42   46   * As swapcontext() is actually equivalent to getcontext() + setcontext(),
  43   47   * swapcontext() shares the most code with getcontext().
  44   48   */
  45   49  
  46   50  
  47      -#define GETCONTEXT_IMPL                                                 \
       51 +#define GETCONTEXT_IMPL(func)                                           \
  48   52          movl    4(%esp), %eax;          /* %eax <-- first arg: ucp */   \
  49   53          pushl   %eax;                   /* push ucp for system call */  \
  50      -        call    __getcontext;           /* call getcontext: syscall */  \
       54 +        call    func;                   /* call getcontext: syscall */  \
  51   55          addl    $4, %esp;               /* pop arg */                   \
  52   56          andl    %eax, %eax;             /* if (err_ret_from_syscall) */ \
  53   57          je      1f;                                                     \
  54   58          ret;                            /*      then return */          \
  55   59  1:                                                                      \
  56   60          movl    4(%esp), %eax;          /* recompute first arg */       \
  57   61          /*                                                              \
  58   62           * fix up %esp and %eip                                         \
  59   63           */                                                             \
  60   64          leal    UC_MCONTEXT_GREGS (%eax), %edx;                         \
↓ open down ↓ 2 lines elided ↑ open up ↑
  63   67          movl    %eax, EIP_OFF (%edx);                                   \
  64   68                                  /* store ret PC in EIP of env var */    \
  65   69          leal    4(%esp), %eax;  /* get caller's sp at time of call */   \
  66   70          movl    %eax, UESP_OFF (%edx);                                  \
  67   71                                  /* store the sp into UESP of env var */ \
  68   72          xorl    %eax, %eax;     /* return 0 */                          \
  69   73          movl    %eax, EAX_OFF (%edx);                                   \
  70   74                                  /* getcontext returns 0 after a setcontext */
  71   75  
  72   76  /*
  73      - * getcontext(ucontext_t *ucp)
       77 + * int getcontext(ucontext_t *ucp)
  74   78   */
  75   79          ENTRY(getcontext)
  76      -        GETCONTEXT_IMPL
       80 +        GETCONTEXT_IMPL(__getcontext)
  77   81          ret
  78   82          SET_SIZE(getcontext)
  79   83  
  80   84  
  81   85  /*
  82      - * swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
       86 + * int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
  83   87   */
  84   88          ENTRY(swapcontext)
  85      -        GETCONTEXT_IMPL
  86      -        / call setcontext
       89 +        GETCONTEXT_IMPL(__getcontext)
       90 +        /* call setcontext */
  87   91          movl    8(%esp), %eax           /* %eax <-- second arg: ucp */
  88   92          pushl   %eax                    /* push ucp for setcontext */
  89   93          call    setcontext
  90   94          addl    $4, %esp                /* pop arg: just in case */
  91   95          ret
  92   96          SET_SIZE(swapcontext)
       97 +
       98 +/*
       99 + * int getcontext_extd(ucontext_t *ucp, uint32_t flags)
      100 + */
      101 +        ENTRY(getcontext_extd)
      102 +        movl    8(%esp), %eax
      103 +        cmpl    $0, %eax                /* if (flags != 0) */
      104 +        jne     2f
      105 +        GETCONTEXT_IMPL(__getcontext_extd)
      106 +        ret
      107 +2:
      108 +        movl    $EINVAL, %eax           /* errno = EINVAL; */
      109 +        jmp     __cerror                /* return (-1) */
      110 +        SET_SIZE(getcontext_extd)
      111 +
      112 +
      113 +/*
      114 + * int swapcontext_extd(ucontext_t *oucp, const ucontext_t *ucp)
      115 + */
      116 +        ENTRY(swapcontext_extd)
      117 +        movl    8(%esp), %eax
      118 +        cmpl    $0, %eax                /* if (flags != 0) */
      119 +        jne     2f
      120 +        GETCONTEXT_IMPL(__getcontext_extd)
      121 +        /* call setcontext */
      122 +        movl    12(%esp), %eax          /* %eax <-- second arg: ucp */
      123 +        pushl   %eax                    /* push ucp for setcontext */
      124 +        call    setcontext
      125 +        addl    $4, %esp                /* pop arg: just in case */
      126 +        ret
      127 +2:
      128 +        movl    $EINVAL, %eax           /* errno = EINVAL; */
      129 +        jmp     __cerror                /* return (-1) */
      130 +        SET_SIZE(swapcontext_extd)
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX