1 /* Copyright (C) 1998-2022 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 regiters 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 guarenteed 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 */
305