1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 
10 /*          Copyright Sean Kelly 2005 - 2009.
11  * Distributed under the Boost Software License, Version 1.0.
12  *    (See accompanying file LICENSE or copy at
13  *          http://www.boost.org/LICENSE_1_0.txt)
14  */
15 module core.sys.posix.setjmp;
16 
17 import core.sys.posix.config;
18 import core.sys.posix.signal; // for sigset_t
19 
20 version (Posix):
21 extern (C) nothrow @nogc:
22 
23 version (RISCV32) version = RISCV_Any;
24 version (RISCV64) version = RISCV_Any;
25 version (PPC) version = PPC_Any;
26 version (PPC64) version = PPC_Any;
27 
28 //
29 // Required
30 //
31 /*
32 jmp_buf
33 
34 int  setjmp(ref jmp_buf);
35 void longjmp(ref jmp_buf, int);
36 */
37 
38 version (CRuntime_Glibc)
39 {
40     version (X86_64)
41     {
42         //enum JB_BX      = 0;
43         //enum JB_BP      = 1;
44         //enum JB_12      = 2;
45         //enum JB_13      = 3;
46         //enum JB_14      = 4;
47         //enum JB_15      = 5;
48         //enum JB_SP      = 6;
49         //enum JB_PC      = 7;
50         //enum JB_SIZE    = 64;
51 
52         alias long[8] __jmp_buf;
53     }
54     else version (X86)
55     {
56         //enum JB_BX      = 0;
57         //enum JB_SI      = 1;
58         //enum JB_DI      = 2;
59         //enum JB_BP      = 3;
60         //enum JB_SP      = 4;
61         //enum JB_PC      = 5;
62         //enum JB_SIZE    = 24;
63 
64         alias int[6] __jmp_buf;
65     }
66     else version (SPARC)
67     {
68         alias int[3] __jmp_buf;
69     }
70     else version (SPARC64)
71     {
72         alias __jmp_buf = ulong[22];
73     }
74     else version (AArch64)
75     {
76         alias long[22] __jmp_buf;
77     }
78     else version (ARM)
79     {
80         alias int[64] __jmp_buf;
81     }
82     else version (HPPA)
83     {
84         struct __jmp_buf
85         {
86             int __r3;
87             int[15] __r4_r18;
88             int __r19;
89             int __r27;
90             int __sp;
91             int __rp;
92             int __pad1;
93             double[10] __fr12_fr21;
94         }
95     }
96     else version (PPC)
97     {
98         alias int[64 + (12*4)] __jmp_buf;
99     }
100     else version (PPC64)
101     {
102         alias long[64] __jmp_buf;
103     }
104     else version (MIPS32)
105     {
106         struct __jmp_buf
107         {
108             version (MIPS_O32)
109             {
110                 void * __pc;
111                 void * __sp;
112                 int[8] __regs;
113                 void * __fp;
114                 void * __gp;
115             }
116             else
117             {
118                 long __pc;
119                 long __sp;
120                 long[8] __regs;
121                 long __fp;
122                 long __gp;
123             }
124             int __fpc_csr;
125             version (MIPS_N64)
126                 double[8] __fpregs;
127             else
128                 double[6] __fpregs;
129         }
130     }
131     else version (MIPS64)
132     {
133         struct __jmp_buf
134         {
135             long __pc;
136             long __sp;
137             long[8] __regs;
138             long __fp;
139             long __gp;
140             int __fpc_csr;
141             version (MIPS_N64)
142                 double[8] __fpregs;
143             else
144                 double[6] __fpregs;
145         }
146     }
147     else version (RISCV_Any)
148     {
149         struct __riscv_jmp_buf
150         {
151             c_long __pc;
152             c_long[12] __regs;
153             c_long __sp;
154             static if (__traits(getTargetInfo, "floatAbi") == "double")
155                 double[12] __fpregs;
156         }
157         alias __jmp_buf = __riscv_jmp_buf[1];
158     }
159     else version (S390)
160     {
161         struct __s390_jmp_buf
162         {
163             c_long[10] __gregs;
164             c_long[4] __fpregs;
165         }
166         alias __jmp_buf = __s390_jmp_buf[1];
167     }
168     else version (SystemZ)
169     {
170         struct __s390_jmp_buf
171         {
172             c_long[10] __gregs;
173             c_long[8] __fpregs;
174         }
175         alias __jmp_buf = __s390_jmp_buf[1];
176     }
177     else
178         static assert(0, "unimplemented");
179 
180     struct __jmp_buf_tag
181     {
182         __jmp_buf   __jmpbuf;
183         int         __mask_was_saved;
184         sigset_t    __saved_mask;
185     }
186 
187     alias __jmp_buf_tag[1] jmp_buf;
188 
189     alias _setjmp setjmp; // see XOpen block
190     void longjmp(ref jmp_buf, int);
191 }
192 else version (FreeBSD)
193 {
194     // <machine/setjmp.h>
195     version (X86)
196     {
197         enum _JBLEN = 11;
198         struct _jmp_buf { int[_JBLEN + 1] _jb; }
199     }
200     else version (X86_64)
201     {
202         enum _JBLEN = 12;
203         struct _jmp_buf { c_long[_JBLEN] _jb; }
204     }
205     else version (SPARC)
206     {
207         enum _JBLEN = 5;
208         struct _jmp_buf { c_long[_JBLEN + 1] _jb; }
209     }
210     else version (AArch64)
211     {
212         enum _JBLEN = 31;
213         // __int128_t
214         struct _jmp_buf { long[2][_JBLEN + 1] _jb; }
215     }
216     else version (PPC_Any)
217     {
218         enum _JBLEN = 100;
219         struct _jmp_buf { long[_JBLEN + 1] _jb; }
220     }
221     else
222         static assert(0);
223     alias _jmp_buf[1] jmp_buf;
224 
225     int  setjmp(ref jmp_buf);
226     void longjmp(ref jmp_buf, int);
227 }
228 else version (NetBSD)
229 {
230     // <machine/setjmp.h>
231     version (X86)
232     {
233         enum _JBLEN = 13;
234         struct _jmp_buf { int[_JBLEN + 1] _jb; }
235     }
236     else version (X86_64)
237     {
238         enum _JBLEN = 11;
239         struct _jmp_buf { c_long[_JBLEN] _jb; }
240     }
241     else
242         static assert(0);
243     alias _jmp_buf[_JBLEN] jmp_buf;
244 
245     int  setjmp(ref jmp_buf);
246     void longjmp(ref jmp_buf, int);
247 }
248 else version (OpenBSD)
249 {
250     // <machine/setjmp.h>
251     version (X86)
252     {
253         enum _JBLEN = 10;
254     }
255     else version (X86_64)
256     {
257         enum _JBLEN = 11;
258     }
259     else version (ARM)
260     {
261         enum _JBLEN = 64;
262     }
263     else version (AArch64)
264     {
265         enum _JBLEN = 64;
266     }
267     else version (PPC)
268     {
269         enum _JBLEN = 100;
270     }
271     else version (MIPS64)
272     {
273         enum _JBLEN = 83;
274     }
275     else version (SPARC)
276     {
277         enum _JBLEN = 10;
278     }
279     else version (SPARC64)
280     {
281         enum _JBLEN = 14;
282     }
283     else
284         static assert(0);
285 
286     alias jmp_buf = c_long[_JBLEN];
287 
288     int  setjmp(ref jmp_buf);
289     void longjmp(ref jmp_buf, int);
290 }
291 else version (DragonFlyBSD)
292 {
293     // <machine/setjmp.h>
294     version (X86_64)
295     {
296         enum _JBLEN = 12;
297         struct _jmp_buf { c_long[_JBLEN] _jb; }
298     }
299     else
300         static assert(0);
301     alias _jmp_buf[1] jmp_buf;
302 
303     int  setjmp(ref jmp_buf);
304     void longjmp(ref jmp_buf, int);
305 }
306 else version (CRuntime_Bionic)
307 {
308     // <machine/setjmp.h>
309     version (X86)
310     {
311         enum _JBLEN = 10;
312     }
313     else version (ARM)
314     {
315         enum _JBLEN = 64;
316     }
317     else version (AArch64)
318     {
319         enum _JBLEN = 32;
320     }
321     else version (X86_64)
322     {
323         enum _JBLEN = 11;
324     }
325     else
326     {
327         static assert(false, "Architecture not supported.");
328     }
329 
330     alias c_long[_JBLEN] jmp_buf;
331 
332     int  setjmp(ref jmp_buf);
333     void longjmp(ref jmp_buf, int);
334 }
335 else version (CRuntime_UClibc)
336 {
337     version (X86_64)
338     {
339         alias long[8] __jmp_buf;
340     }
341     else version (ARM)
342     {
343         align(8) alias int[64] __jmp_buf;
344     }
345     else version (MIPS32)
346     {
347         struct __jmp_buf
348         {
349             version (MIPS_O32)
350             {
351                 void * __pc;
352                 void * __sp;
353                 int[8] __regs;
354                 void * __fp;
355                 void * __gp;
356             }
357             else
358             {
359                 long __pc;
360                 long __sp;
361                 long[8] __regs;
362                 long __fp;
363                 long __gp;
364             }
365             int __fpc_csr;
366             version (MIPS_N64)
367                 double[8] __fpregs;
368             else
369                 double[6] __fpregs;
370         }
371     }
372     else version (MIPS64)
373     {
374         struct __jmp_buf
375         {
376             long __pc;
377             long __sp;
378             long[8] __regs;
379             long __fp;
380             long __gp;
381             int __fpc_csr;
382             version (MIPS_N64)
383                 double[8] __fpregs;
384             else
385                 double[6] __fpregs;
386         }
387     }
388     else
389         static assert(0, "unimplemented");
390 
391     struct __jmp_buf_tag
392     {
393         __jmp_buf   __jmpbuf;
394         int         __mask_was_saved;
395         sigset_t    __saved_mask;
396     }
397 
398     alias __jmp_buf_tag[1] jmp_buf;
399 
400     alias _setjmp setjmp;
401     void longjmp(ref jmp_buf, int);
402 }
403 
404 //
405 // C Extension (CX)
406 //
407 /*
408 sigjmp_buf
409 
410 int  sigsetjmp(sigjmp_buf, int);
411 void siglongjmp(sigjmp_buf, int);
412 */
413 
414 version (CRuntime_Glibc)
415 {
416     alias jmp_buf sigjmp_buf;
417 
418     int __sigsetjmp(sigjmp_buf, int);
419     alias __sigsetjmp sigsetjmp;
420     void siglongjmp(sigjmp_buf, int);
421 }
422 else version (FreeBSD)
423 {
424     // <machine/setjmp.h>
425     version (X86)
426     {
427         struct _sigjmp_buf { int[_JBLEN + 1] _ssjb; }
428     }
429     else version (X86_64)
430     {
431         struct _sigjmp_buf { c_long[_JBLEN] _sjb; }
432     }
433     else version (SPARC)
434     {
435         enum _JBLEN         = 5;
436         enum _JB_FP         = 0;
437         enum _JB_PC         = 1;
438         enum _JB_SP         = 2;
439         enum _JB_SIGMASK    = 3;
440         enum _JB_SIGFLAG    = 5;
441         struct _sigjmp_buf { c_long[_JBLEN + 1] _sjb; }
442     }
443     else version (AArch64)
444     {
445         // __int128_t
446         struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; }
447     }
448     else version (PPC_Any)
449     {
450         struct _sigjmp_buf { long[_JBLEN + 1] _sjb; }
451     }
452     else
453         static assert(0);
454     alias _sigjmp_buf[1] sigjmp_buf;
455 
456     int  sigsetjmp(ref sigjmp_buf);
457     void siglongjmp(ref sigjmp_buf, int);
458 }
459 else version (NetBSD)
460 {
461     // <machine/setjmp.h>
462     version (X86)
463     {
464         struct _sigjmp_buf { int[_JBLEN + 1] _ssjb; }
465     }
466     else version (X86_64)
467     {
468         struct _sigjmp_buf { c_long[_JBLEN] _sjb; }
469     }
470     else
471         static assert(0);
472     alias _sigjmp_buf[_JBLEN + 1] sigjmp_buf;
473 
474     int  sigsetjmp(ref sigjmp_buf);
475     void siglongjmp(ref sigjmp_buf, int);
476 }
477 else version (OpenBSD)
478 {
479     alias sigjmp_buf = c_long[_JBLEN + 1];
480 
481     int  sigsetjmp(ref sigjmp_buf);
482     void siglongjmp(ref sigjmp_buf, int);
483 }
484 else version (DragonFlyBSD)
485 {
486     // <machine/setjmp.h>
487     version (X86_64)
488     {
489         struct _sigjmp_buf { c_long[_JBLEN] _sjb; }
490     }
491     else
492         static assert(0);
493     alias _sigjmp_buf[1] sigjmp_buf;
494 
495     int  sigsetjmp(ref sigjmp_buf);
496     void siglongjmp(ref sigjmp_buf, int);
497 }
498 else version (CRuntime_Bionic)
499 {
500     alias c_long[_JBLEN + 1] sigjmp_buf;
501 
502     int  sigsetjmp(ref sigjmp_buf, int);
503     void siglongjmp(ref sigjmp_buf, int);
504 }
505 else version (CRuntime_UClibc)
506 {
507     alias jmp_buf sigjmp_buf;
508 
509     int __sigsetjmp(ref sigjmp_buf, int);
510     alias __sigsetjmp sigsetjmp;
511     void siglongjmp(ref sigjmp_buf, int);
512 }
513 
514 //
515 // XOpen (XSI)
516 //
517 /*
518 int  _setjmp(jmp_buf);
519 void _longjmp(jmp_buf, int);
520 */
521 
522 version (CRuntime_Glibc)
523 {
524     int  _setjmp(ref jmp_buf);
525     void _longjmp(ref jmp_buf, int);
526 }
527 else version (FreeBSD)
528 {
529     int  _setjmp(ref jmp_buf);
530     void _longjmp(ref jmp_buf, int);
531 }
532 else version (NetBSD)
533 {
534     int  _setjmp(ref jmp_buf);
535     void _longjmp(ref jmp_buf, int);
536 }
537 else version (OpenBSD)
538 {
539     int  _setjmp(ref jmp_buf);
540     void _longjmp(ref jmp_buf, int);
541 }
542 else version (DragonFlyBSD)
543 {
544     int  _setjmp(ref jmp_buf);
545     void _longjmp(ref jmp_buf, int);
546 }
547 else version (CRuntime_Bionic)
548 {
549     int  _setjmp(ref jmp_buf);
550     void _longjmp(ref jmp_buf, int);
551 }
552 else version (CRuntime_UClibc)
553 {
554     int  _setjmp(ref jmp_buf);
555     void _longjmp(ref jmp_buf, int);
556 }