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