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