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 version (LoongArch64)
178     {
179         struct __loongarch_jmp_buf
180         {
181             long __pc;
182             long __sp;
183             // reserved
184             long __r21;
185             long __fp;
186             long[9] __regs;
187             static if (__traits(getTargetInfo, "floatAbi") != "soft_float")
188                 double[8] __fpregs;
189         }
190         alias __jmp_buf = __loongarch_jmp_buf[1];
191     }
192     else
193         static assert(0, "unimplemented");
194 
195     struct __jmp_buf_tag
196     {
197         __jmp_buf   __jmpbuf;
198         int         __mask_was_saved;
199         sigset_t    __saved_mask;
200     }
201 
202     alias __jmp_buf_tag[1] jmp_buf;
203 
204     alias _setjmp setjmp; // see XOpen block
205     void longjmp(ref jmp_buf, int);
206 }
207 else version (FreeBSD)
208 {
209     // <machine/setjmp.h>
210     version (X86)
211     {
212         enum _JBLEN = 11;
213         struct _jmp_buf { int[_JBLEN + 1] _jb; }
214     }
215     else version (X86_64)
216     {
217         enum _JBLEN = 12;
218         struct _jmp_buf { c_long[_JBLEN] _jb; }
219     }
220     else version (SPARC)
221     {
222         enum _JBLEN = 5;
223         struct _jmp_buf { c_long[_JBLEN + 1] _jb; }
224     }
225     else version (AArch64)
226     {
227         enum _JBLEN = 31;
228         // __int128_t
229         struct _jmp_buf { long[2][_JBLEN + 1] _jb; }
230     }
231     else version (PPC_Any)
232     {
233         enum _JBLEN = 100;
234         struct _jmp_buf { long[_JBLEN + 1] _jb; }
235     }
236     else
237         static assert(0);
238     alias _jmp_buf[1] jmp_buf;
239 
240     int  setjmp(ref jmp_buf);
241     void longjmp(ref jmp_buf, int);
242 }
243 else version (NetBSD)
244 {
245     // <machine/setjmp.h>
246     version (X86)
247     {
248         enum _JBLEN = 13;
249         struct _jmp_buf { int[_JBLEN + 1] _jb; }
250     }
251     else version (X86_64)
252     {
253         enum _JBLEN = 11;
254         struct _jmp_buf { c_long[_JBLEN] _jb; }
255     }
256     else
257         static assert(0);
258     alias _jmp_buf[_JBLEN] jmp_buf;
259 
260     int  setjmp(ref jmp_buf);
261     void longjmp(ref jmp_buf, int);
262 }
263 else version (OpenBSD)
264 {
265     // <machine/setjmp.h>
266     version (X86)
267     {
268         enum _JBLEN = 10;
269     }
270     else version (X86_64)
271     {
272         enum _JBLEN = 11;
273     }
274     else version (ARM)
275     {
276         enum _JBLEN = 64;
277     }
278     else version (AArch64)
279     {
280         enum _JBLEN = 64;
281     }
282     else version (PPC)
283     {
284         enum _JBLEN = 100;
285     }
286     else version (MIPS64)
287     {
288         enum _JBLEN = 83;
289     }
290     else version (SPARC)
291     {
292         enum _JBLEN = 10;
293     }
294     else version (SPARC64)
295     {
296         enum _JBLEN = 14;
297     }
298     else
299         static assert(0);
300 
301     alias jmp_buf = c_long[_JBLEN];
302 
303     int  setjmp(ref jmp_buf);
304     void longjmp(ref jmp_buf, int);
305 }
306 else version (DragonFlyBSD)
307 {
308     // <machine/setjmp.h>
309     version (X86_64)
310     {
311         enum _JBLEN = 12;
312         struct _jmp_buf { c_long[_JBLEN] _jb; }
313     }
314     else
315         static assert(0);
316     alias _jmp_buf[1] jmp_buf;
317 
318     int  setjmp(ref jmp_buf);
319     void longjmp(ref jmp_buf, int);
320 }
321 else version (CRuntime_Bionic)
322 {
323     // <machine/setjmp.h>
324     version (X86)
325     {
326         enum _JBLEN = 10;
327     }
328     else version (ARM)
329     {
330         enum _JBLEN = 64;
331     }
332     else version (AArch64)
333     {
334         enum _JBLEN = 32;
335     }
336     else version (X86_64)
337     {
338         enum _JBLEN = 11;
339     }
340     else
341     {
342         static assert(false, "Architecture not supported.");
343     }
344 
345     alias c_long[_JBLEN] jmp_buf;
346 
347     int  setjmp(ref jmp_buf);
348     void longjmp(ref jmp_buf, int);
349 }
350 else version (CRuntime_UClibc)
351 {
352     version (X86_64)
353     {
354         alias long[8] __jmp_buf;
355     }
356     else version (ARM)
357     {
358         align(8) alias int[64] __jmp_buf;
359     }
360     else version (MIPS32)
361     {
362         struct __jmp_buf
363         {
364             version (MIPS_O32)
365             {
366                 void * __pc;
367                 void * __sp;
368                 int[8] __regs;
369                 void * __fp;
370                 void * __gp;
371             }
372             else
373             {
374                 long __pc;
375                 long __sp;
376                 long[8] __regs;
377                 long __fp;
378                 long __gp;
379             }
380             int __fpc_csr;
381             version (MIPS_N64)
382                 double[8] __fpregs;
383             else
384                 double[6] __fpregs;
385         }
386     }
387     else version (MIPS64)
388     {
389         struct __jmp_buf
390         {
391             long __pc;
392             long __sp;
393             long[8] __regs;
394             long __fp;
395             long __gp;
396             int __fpc_csr;
397             version (MIPS_N64)
398                 double[8] __fpregs;
399             else
400                 double[6] __fpregs;
401         }
402     }
403     else
404         static assert(0, "unimplemented");
405 
406     struct __jmp_buf_tag
407     {
408         __jmp_buf   __jmpbuf;
409         int         __mask_was_saved;
410         sigset_t    __saved_mask;
411     }
412 
413     alias __jmp_buf_tag[1] jmp_buf;
414 
415     alias _setjmp setjmp;
416     void longjmp(ref jmp_buf, int);
417 }
418 
419 //
420 // C Extension (CX)
421 //
422 /*
423 sigjmp_buf
424 
425 int  sigsetjmp(sigjmp_buf, int);
426 void siglongjmp(sigjmp_buf, int);
427 */
428 
429 version (CRuntime_Glibc)
430 {
431     alias jmp_buf sigjmp_buf;
432 
433     int __sigsetjmp(sigjmp_buf, int);
434     alias __sigsetjmp sigsetjmp;
435     void siglongjmp(sigjmp_buf, int);
436 }
437 else version (FreeBSD)
438 {
439     // <machine/setjmp.h>
440     version (X86)
441     {
442         struct _sigjmp_buf { int[_JBLEN + 1] _ssjb; }
443     }
444     else version (X86_64)
445     {
446         struct _sigjmp_buf { c_long[_JBLEN] _sjb; }
447     }
448     else version (SPARC)
449     {
450         enum _JBLEN         = 5;
451         enum _JB_FP         = 0;
452         enum _JB_PC         = 1;
453         enum _JB_SP         = 2;
454         enum _JB_SIGMASK    = 3;
455         enum _JB_SIGFLAG    = 5;
456         struct _sigjmp_buf { c_long[_JBLEN + 1] _sjb; }
457     }
458     else version (AArch64)
459     {
460         // __int128_t
461         struct _sigjmp_buf { long[2][_JBLEN + 1] _jb; }
462     }
463     else version (PPC_Any)
464     {
465         struct _sigjmp_buf { long[_JBLEN + 1] _sjb; }
466     }
467     else
468         static assert(0);
469     alias _sigjmp_buf[1] sigjmp_buf;
470 
471     int  sigsetjmp(ref sigjmp_buf);
472     void siglongjmp(ref sigjmp_buf, int);
473 }
474 else version (NetBSD)
475 {
476     // <machine/setjmp.h>
477     version (X86)
478     {
479         struct _sigjmp_buf { int[_JBLEN + 1] _ssjb; }
480     }
481     else version (X86_64)
482     {
483         struct _sigjmp_buf { c_long[_JBLEN] _sjb; }
484     }
485     else
486         static assert(0);
487     alias _sigjmp_buf[_JBLEN + 1] sigjmp_buf;
488 
489     int  sigsetjmp(ref sigjmp_buf);
490     void siglongjmp(ref sigjmp_buf, int);
491 }
492 else version (OpenBSD)
493 {
494     alias sigjmp_buf = c_long[_JBLEN + 1];
495 
496     int  sigsetjmp(ref sigjmp_buf);
497     void siglongjmp(ref sigjmp_buf, int);
498 }
499 else version (DragonFlyBSD)
500 {
501     // <machine/setjmp.h>
502     version (X86_64)
503     {
504         struct _sigjmp_buf { c_long[_JBLEN] _sjb; }
505     }
506     else
507         static assert(0);
508     alias _sigjmp_buf[1] sigjmp_buf;
509 
510     int  sigsetjmp(ref sigjmp_buf);
511     void siglongjmp(ref sigjmp_buf, int);
512 }
513 else version (CRuntime_Bionic)
514 {
515     alias c_long[_JBLEN + 1] sigjmp_buf;
516 
517     int  sigsetjmp(ref sigjmp_buf, int);
518     void siglongjmp(ref sigjmp_buf, int);
519 }
520 else version (CRuntime_UClibc)
521 {
522     alias jmp_buf sigjmp_buf;
523 
524     int __sigsetjmp(ref sigjmp_buf, int);
525     alias __sigsetjmp sigsetjmp;
526     void siglongjmp(ref sigjmp_buf, int);
527 }
528 
529 //
530 // XOpen (XSI)
531 //
532 /*
533 int  _setjmp(jmp_buf);
534 void _longjmp(jmp_buf, int);
535 */
536 
537 version (CRuntime_Glibc)
538 {
539     int  _setjmp(ref jmp_buf);
540     void _longjmp(ref jmp_buf, int);
541 }
542 else version (FreeBSD)
543 {
544     int  _setjmp(ref jmp_buf);
545     void _longjmp(ref jmp_buf, int);
546 }
547 else version (NetBSD)
548 {
549     int  _setjmp(ref jmp_buf);
550     void _longjmp(ref jmp_buf, int);
551 }
552 else version (OpenBSD)
553 {
554     int  _setjmp(ref jmp_buf);
555     void _longjmp(ref jmp_buf, int);
556 }
557 else version (DragonFlyBSD)
558 {
559     int  _setjmp(ref jmp_buf);
560     void _longjmp(ref jmp_buf, int);
561 }
562 else version (CRuntime_Bionic)
563 {
564     int  _setjmp(ref jmp_buf);
565     void _longjmp(ref jmp_buf, int);
566 }
567 else version (CRuntime_UClibc)
568 {
569     int  _setjmp(ref jmp_buf);
570     void _longjmp(ref jmp_buf, int);
571 }