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  #include <bits/wordsize.h>
      27  
      28  
      29  #ifdef __USE_MISC
      30  # define __ctx(fld) fld
      31  #else
      32  # define __ctx(fld) __ ## fld
      33  #endif
      34  
      35  #if __WORDSIZE == 64
      36  
      37  #define __MC_NGREG	19
      38  #ifdef __USE_MISC
      39  # define MC_TSTATE	0
      40  # define MC_PC		1
      41  # define MC_NPC		2
      42  # define MC_Y		3
      43  # define MC_G1		4
      44  # define MC_G2		5
      45  # define MC_G3		6
      46  # define MC_G4		7
      47  # define MC_G5		8
      48  # define MC_G6		9
      49  # define MC_G7		10
      50  # define MC_O0		11
      51  # define MC_O1		12
      52  # define MC_O2		13
      53  # define MC_O3		14
      54  # define MC_O4		15
      55  # define MC_O5		16
      56  # define MC_O6		17
      57  # define MC_O7		18
      58  # define MC_NGREG	__MC_NGREG
      59  #endif
      60  
      61  typedef unsigned long mc_greg_t;
      62  typedef mc_greg_t mc_gregset_t[__MC_NGREG];
      63  
      64  #ifdef __USE_MISC
      65  # define MC_MAXFPQ	16
      66  #endif
      67  struct __mc_fq {
      68  	unsigned long	*__ctx(mcfq_addr);
      69  	unsigned int	__ctx(mcfq_insn);
      70  };
      71  
      72  typedef struct {
      73  	union {
      74  		unsigned int	__ctx(sregs)[32];
      75  		unsigned long	__ctx(dregs)[32];
      76  		long double	__ctx(qregs)[16];
      77  	} __ctx(mcfpu_fregs);
      78  	unsigned long	__ctx(mcfpu_fsr);
      79  	unsigned long	__ctx(mcfpu_fprs);
      80  	unsigned long	__ctx(mcfpu_gsr);
      81  	struct __mc_fq	*__ctx(mcfpu_fq);
      82  	unsigned char	__ctx(mcfpu_qcnt);
      83  	unsigned char	__ctx(mcfpu_qentsz);
      84  	unsigned char	__ctx(mcfpu_enab);
      85  } mc_fpu_t;
      86  
      87  typedef struct {
      88  	mc_gregset_t	__ctx(mc_gregs);
      89  	mc_greg_t	__ctx(mc_fp);
      90  	mc_greg_t	__ctx(mc_i7);
      91  	mc_fpu_t	__ctx(mc_fpregs);
      92  } mcontext_t;
      93  
      94  typedef struct ucontext_t {
      95  	struct ucontext_t	*uc_link;
      96  	unsigned long		__ctx(uc_flags);
      97  	unsigned long		__uc_sigmask;
      98  	mcontext_t		uc_mcontext;
      99  	stack_t			uc_stack;
     100  	sigset_t		uc_sigmask;
     101  } ucontext_t;
     102  
     103  #endif /* __WORDISIZE == 64 */
     104  
     105  /*
     106   * Location of the users' stored registers relative to R0.
     107   * Usage is as an index into a gregset_t array or as u.u_ar0[XX].
     108   */
     109  #ifdef __USE_MISC
     110  # define REG_PSR (0)
     111  # define REG_PC  (1)
     112  # define REG_nPC (2)
     113  # define REG_Y   (3)
     114  # define REG_G1  (4)
     115  # define REG_G2  (5)
     116  # define REG_G3  (6)
     117  # define REG_G4  (7)
     118  # define REG_G5  (8)
     119  # define REG_G6  (9)
     120  # define REG_G7  (10)
     121  # define REG_O0  (11)
     122  # define REG_O1  (12)
     123  # define REG_O2  (13)
     124  # define REG_O3  (14)
     125  # define REG_O4  (15)
     126  # define REG_O5  (16)
     127  # define REG_O6  (17)
     128  # define REG_O7  (18)
     129  #endif
     130  
     131  /*
     132   * A gregset_t is defined as an array type for compatibility with the reference
     133   * source. This is important due to differences in the way the C language
     134   * treats arrays and structures as parameters.
     135   *
     136   * Note that NGREG is really (sizeof (struct regs) / sizeof (greg_t)),
     137   * but that the ABI defines it absolutely to be 21 (resp. 19).
     138   */
     139  
     140  #if __WORDSIZE == 64
     141  
     142  # define __NGREG   21
     143  # ifdef __USE_MISC
     144  #  define REG_ASI	(19)
     145  #  define REG_FPRS (20)
     146  
     147  #  define NGREG   __NGREG
     148  # endif
     149  typedef long greg_t;
     150  
     151  #else /* __WORDSIZE == 32 */
     152  
     153  # define __NGREG   19
     154  # ifdef __USE_MISC
     155  #  define NGREG   __NGREG
     156  # endif
     157  typedef int greg_t;
     158  
     159  #endif /* __WORDSIZE == 32 */
     160  
     161  typedef greg_t  gregset_t[__NGREG];
     162  
     163  /*
     164   * The following structures define how a register window can appear on the
     165   * stack. This structure is available (when required) through the `gwins'
     166   * field of an mcontext (nested within ucontext). SPARC_MAXWINDOW is the
     167   * maximum number of outstanding registers window defined in the SPARC
     168   * architecture (*not* implementation).
     169   */
     170  # define __SPARC_MAXREGWINDOW	31	/* max windows in SPARC arch. */
     171  #ifdef __USE_MISC
     172  # define SPARC_MAXREGWINDOW	__SPARC_MAXREGWINDOW
     173  #endif
     174  struct  __rwindow
     175    {
     176      greg_t __ctx(rw_local)[8];			/* locals */
     177      greg_t __ctx(rw_in)[8];			/* ins */
     178    };
     179  
     180  #ifdef __USE_MISC
     181  # define rw_fp   __ctx(rw_in)[6]		/* frame pointer */
     182  # define rw_rtn  __ctx(rw_in)[7]		/* return address */
     183  #endif
     184  
     185  typedef struct
     186    {
     187      int            __ctx(wbcnt);
     188      int           *__ctx(spbuf)[__SPARC_MAXREGWINDOW];
     189      struct __rwindow __ctx(wbuf)[__SPARC_MAXREGWINDOW];
     190    } gwindows_t;
     191  
     192  /*
     193   * Floating point definitions.
     194   */
     195  
     196  #ifdef __USE_MISC
     197  # define MAXFPQ	16	/* max # of fpu queue entries currently supported */
     198  #endif
     199  
     200  /*
     201   * struct fq defines the minimal format of a floating point instruction queue
     202   * entry. The size of entries in the floating point queue are implementation
     203   * dependent. The union FQu is guaranteed to be the first field in any ABI
     204   * conformant system implementation. Any additional fields provided by an
     205   * implementation should not be used applications designed to be ABI conformant. */
     206  
     207  struct __fpq
     208    {
     209      unsigned long *__ctx(fpq_addr);		/* address */
     210      unsigned long __ctx(fpq_instr);		/* instruction */
     211    };
     212  
     213  struct __fq
     214    {
     215      union				/* FPU inst/addr queue */
     216        {
     217          double __ctx(whole);
     218          struct __fpq __ctx(fpq);
     219        } __ctx(FQu);
     220    };
     221  
     222  #ifdef __USE_MISC
     223  # define FPU_REGS_TYPE           unsigned
     224  # define FPU_DREGS_TYPE          unsigned long long
     225  # define V7_FPU_FSR_TYPE         unsigned
     226  # define V9_FPU_FSR_TYPE         unsigned long long
     227  # define V9_FPU_FPRS_TYPE        unsigned
     228  #endif
     229  
     230  #if __WORDSIZE == 64
     231  
     232  typedef struct
     233    {
     234      union {				/* FPU floating point regs */
     235        unsigned		__ctx(fpu_regs)[32];	/* 32 singles */
     236        double            __ctx(fpu_dregs)[32];	/* 32 doubles */
     237        long double	__ctx(fpu_qregs)[16];  /* 16 quads */
     238      } __ctx(fpu_fr);
     239      struct __fq     *__ctx(fpu_q);		/* ptr to array of FQ entries */
     240      unsigned long   __ctx(fpu_fsr);		/* FPU status register */
     241      unsigned char   __ctx(fpu_qcnt);		/* # of entries in saved FQ */
     242      unsigned char   __ctx(fpu_q_entrysize);	/* # of bytes per FQ entry */
     243      unsigned char   __ctx(fpu_en);		/* flag signifying fpu in use */
     244    } fpregset_t;
     245  
     246  #else /* __WORDSIZE == 32 */
     247  
     248  typedef struct
     249    {
     250      union {				/* FPU floating point regs */
     251        __extension__ unsigned long long __ctx(fpu_regs)[32];	/* 32 singles */
     252        double             __ctx(fpu_dregs)[16];	/* 16 doubles */
     253      } __ctx(fpu_fr);
     254      struct __fq     *__ctx(fpu_q);		/* ptr to array of FQ entries */
     255      unsigned        __ctx(fpu_fsr);		/* FPU status register */
     256      unsigned char   __ctx(fpu_qcnt);		/* # of entries in saved FQ */
     257      unsigned char   __ctx(fpu_q_entrysize);	/* # of bytes per FQ entry */
     258      unsigned char   __ctx(fpu_en);		/* flag signifying fpu in use */
     259    } fpregset_t;
     260  
     261  /*
     262   * The following structure is for associating extra register state with
     263   * the ucontext structure and is kept within the uc_mcontext filler area.
     264   *
     265   * If (xrs_id == XRS_ID) then the xrs_ptr field is a valid pointer to
     266   * extra register state. The exact format of the extra register state
     267   * pointed to by xrs_ptr is platform-dependent.
     268   *
     269   * Note: a platform may or may not manage extra register state.
     270   */
     271  typedef struct
     272    {
     273      unsigned int __ctx(xrs_id);		/* indicates xrs_ptr validity */
     274      void *       __ctx(xrs_ptr);		/* ptr to extra reg state */
     275    } xrs_t;
     276  
     277  #ifdef __USE_MISC
     278  # define XRS_ID	0x78727300		/* the string "xrs" */
     279  #endif
     280  
     281  typedef struct
     282    {
     283      gregset_t   __ctx(gregs);		/* general register set */
     284      gwindows_t  *__ctx(gwins);		/* POSSIBLE pointer to register
     285  					   windows */
     286      fpregset_t  __ctx(fpregs);		/* floating point register set */
     287      xrs_t       __ctx(xrs);		/* POSSIBLE extra register state
     288  					   association */
     289      long        __glibc_reserved1[19];
     290    } mcontext_t;
     291  
     292  
     293  /* Userlevel context.  */
     294  typedef struct ucontext_t
     295    {
     296      unsigned long   __ctx(uc_flags);
     297      struct ucontext_t *uc_link;
     298      sigset_t	    uc_sigmask;
     299      stack_t         uc_stack;
     300      mcontext_t      uc_mcontext;
     301    } ucontext_t;
     302  
     303  #endif /* __WORDSIZE == 32 */
     304  #endif /* sys/ucontext.h */