(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
powerpc/
sys/
ucontext.h
       1  /* Copyright (C) 1998-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef _SYS_UCONTEXT_H
      19  #define _SYS_UCONTEXT_H	1
      20  
      21  #include <features.h>
      22  
      23  #include <bits/types/sigset_t.h>
      24  #include <bits/types/stack_t.h>
      25  
      26  
      27  #ifdef __USE_MISC
      28  # define __ctx(fld) fld
      29  #else
      30  # define __ctx(fld) __ ## fld
      31  #endif
      32  
      33  struct __ctx(pt_regs);
      34  
      35  #if __WORDSIZE == 32
      36  
      37  /* Number of general registers.  */
      38  # define __NGREG	48
      39  # ifdef __USE_MISC
      40  #  define NGREG	__NGREG
      41  # endif
      42  
      43  /* Container for all general registers.  */
      44  typedef unsigned long gregset_t[__NGREG];
      45  
      46  /* Container for floating-point registers and status */
      47  typedef struct _libc_fpstate
      48  {
      49  	double __ctx(fpregs)[32];
      50  	double __ctx(fpscr);
      51  	unsigned int _pad[2];
      52  } fpregset_t;
      53  
      54  /* Container for Altivec/VMX registers and status.
      55     Needs to be aligned on a 16-byte boundary. */
      56  typedef struct _libc_vrstate
      57  {
      58  	unsigned int __ctx(vrregs)[32][4];
      59  	unsigned int __ctx(vrsave);
      60  	unsigned int _pad[2];
      61  	unsigned int __ctx(vscr);
      62  } vrregset_t;
      63  
      64  /* Context to describe whole processor state.  */
      65  typedef struct
      66  {
      67  	gregset_t __ctx(gregs);
      68  	fpregset_t __ctx(fpregs);
      69  	vrregset_t __ctx(vrregs) __attribute__((__aligned__(16)));
      70  } mcontext_t;
      71  
      72  #else
      73  
      74  /* For 64-bit kernels with Altivec support, a machine context is exactly
      75   * a sigcontext.  For older kernel (without Altivec) the sigcontext matches
      76   * the mcontext upto but not including the v_regs field.  For kernels that
      77   * don't set AT_HWCAP or return AT_HWCAP without PPC_FEATURE_HAS_ALTIVEC the
      78   * v_regs field may not exist and should not be referenced.  The v_regs field
      79   * can be referenced safely only after verifying that PPC_FEATURE_HAS_ALTIVEC
      80   * is set in AT_HWCAP.  */
      81  
      82  /* Number of general registers.  */
      83  # define __NGREG	48	/* includes r0-r31, nip, msr, lr, etc.  */
      84  # define __NFPREG	33	/* includes fp0-fp31 &fpscr.  */
      85  # define __NVRREG	34	/* includes v0-v31, vscr, & vrsave in
      86  				   split vectors */
      87  # ifdef __USE_MISC
      88  #  define NGREG	__NGREG
      89  #  define NFPREG	__NFPREG
      90  #  define NVRREG	__NVRREG
      91  # endif
      92  
      93  typedef unsigned long gregset_t[__NGREG];
      94  typedef double fpregset_t[__NFPREG];
      95  
      96  /* Container for Altivec/VMX Vector Status and Control Register.  Only 32-bits
      97     but can only be copied to/from a 128-bit vector register.  So we allocated
      98     a whole quadword speedup save/restore.  */
      99  typedef struct _libc_vscr
     100  {
     101  #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     102  	unsigned int __pad[3];
     103  	unsigned int __ctx(vscr_word);
     104  #else
     105  	unsigned int __ctx(vscr_word);
     106  	unsigned int __pad[3];
     107  #endif
     108  } vscr_t;
     109  
     110  /* Container for Altivec/VMX registers and status.
     111     Must to be aligned on a 16-byte boundary. */
     112  typedef struct _libc_vrstate
     113  {
     114  	unsigned int	__ctx(vrregs)[32][4];
     115  	vscr_t		__ctx(vscr);
     116  	unsigned int	__ctx(vrsave);
     117  	unsigned int	__pad[3];
     118  } vrregset_t  __attribute__((__aligned__(16)));
     119  
     120  typedef struct {
     121  	unsigned long	__glibc_reserved[4];
     122  	int		__ctx(signal);
     123  	int		__pad0;
     124  	unsigned long	__ctx(handler);
     125  	unsigned long	__ctx(oldmask);
     126  	struct __ctx(pt_regs)	*__ctx(regs);
     127  	gregset_t	__ctx(gp_regs);
     128  	fpregset_t	__ctx(fp_regs);
     129  /*
     130   * To maintain compatibility with current implementations the sigcontext is
     131   * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
     132   * followed by an unstructured (vmx_reserve) field of 69 doublewords.  This
     133   * allows the array of vector registers to be quadword aligned independent of
     134   * the alignment of the containing sigcontext or ucontext. It is the
     135   * responsibility of the code setting the sigcontext to set this pointer to
     136   * either NULL (if this processor does not support the VMX feature) or the
     137   * address of the first quadword within the allocated (vmx_reserve) area.
     138   *
     139   * The pointer (v_regs) of vector type (elf_vrreg_t) is essentially
     140   * an array of 34 quadword entries.  The entries with
     141   * indexes 0-31 contain the corresponding vector registers.  The entry with
     142   * index 32 contains the vscr as the last word (offset 12) within the
     143   * quadword.  This allows the vscr to be stored as either a quadword (since
     144   * it must be copied via a vector register to/from storage) or as a word.
     145   * The entry with index 33 contains the vrsave as the first word (offset 0)
     146   * within the quadword.
     147   */
     148  	vrregset_t	*__ctx(v_regs);
     149  	long		__ctx(vmx_reserve)[__NVRREG+__NVRREG+1];
     150  } mcontext_t;
     151  
     152  #endif
     153  
     154  /* Userlevel context.  */
     155  typedef struct ucontext_t
     156    {
     157      unsigned long int __ctx(uc_flags);
     158      struct ucontext_t *uc_link;
     159      stack_t uc_stack;
     160  #if __WORDSIZE == 32
     161      /*
     162       * These fields are set up this way to maximize source and
     163       * binary compatibility with code written for the old
     164       * ucontext_t definition, which didn't include space for the
     165       * registers.
     166       *
     167       * Different versions of the kernel have stored the registers on
     168       * signal delivery at different offsets from the ucontext struct.
     169       * Programs should thus use the uc_mcontext.uc_regs pointer to
     170       * find where the registers are actually stored.  The registers
     171       * will be stored within the ucontext_t struct but not necessarily
     172       * at a fixed address.  As a side-effect, this lets us achieve
     173       * 16-byte alignment for the register storage space if the
     174       * Altivec registers are to be saved, without requiring 16-byte
     175       * alignment on the whole ucontext_t.
     176       *
     177       * The uc_mcontext.regs field is included for source compatibility
     178       * with programs written against the older ucontext_t definition,
     179       * and its name should therefore not change.  The uc_pad field
     180       * is for binary compatibility with programs compiled against the
     181       * old ucontext_t; it ensures that uc_mcontext.regs and uc_sigmask
     182       * are at the same offset as previously.
     183       */
     184      int __glibc_reserved1[7];
     185      union __ctx(uc_regs_ptr) {
     186        struct __ctx(pt_regs) *__ctx(regs);
     187        mcontext_t *__ctx(uc_regs);
     188      } uc_mcontext;
     189      sigset_t    uc_sigmask;
     190      /* last for extensibility */
     191      char __ctx(uc_reg_space)[sizeof (mcontext_t) + 12];
     192  #else /* 64-bit */
     193      sigset_t    uc_sigmask;
     194      mcontext_t  uc_mcontext;  /* last for extensibility */
     195  #endif
     196    } ucontext_t;
     197  
     198  #undef __ctx
     199  
     200  #endif /* sys/ucontext.h */