1 /*      $NetBSD: compat_sigaltstack.h,v 1.4 2021/11/01 05:07:16 thorpej Exp $        */
2 
3 /* Wrapper for calling sigaltstack1() from compat (or other) code */
4 
5 /* Maybe these definitions could be global. */
6 #ifdef SCARG_P32
7 /* compat32 */
8 #define   SCARG_COMPAT_PTR(uap,p)       SCARG_P32(uap, p)
9 #define   COMPAT_GET_PTR(p)   NETBSD32PTR64(p)
10 #define   COMPAT_SET_PTR(p, v)          NETBSD32PTR32(p, v)
11 #else
12 /* not a size change */
13 #define   SCARG_COMPAT_PTR(uap,p)       SCARG(uap, p)
14 #define   COMPAT_GET_PTR(p)   (p)
15 #define   COMPAT_SET_PTR(p, v)          ((p) = (v))
16 #endif
17 
18 #define compat_sigaltstack(uap, compat_ss, ss_onstack, ss_disable) do { \
19           struct compat_ss css; \
20           stack_t nss, oss; \
21           int error; \
22 \
23           if (SCARG_COMPAT_PTR(uap, nss)) { \
24                     error = copyin(SCARG_COMPAT_PTR(uap, nss), &css, sizeof css); \
25                     if (error) \
26                               return error; \
27                     nss.ss_sp = COMPAT_GET_PTR(css.ss_sp); \
28                     nss.ss_size = css.ss_size; \
29                     if (ss_onstack == SS_ONSTACK && ss_disable == SS_DISABLE) \
30                               nss.ss_flags = css.ss_flags; \
31                     else \
32                               nss.ss_flags = \
33                                   (css.ss_flags & ss_onstack ? SS_ONSTACK : 0) \
34                                   | (css.ss_flags & ss_disable ? SS_DISABLE : 0); \
35           } \
36 \
37           error = sigaltstack1(curlwp, SCARG_COMPAT_PTR(uap, nss) ? &nss : 0, \
38                                         SCARG_COMPAT_PTR(uap, oss) ? &oss : 0); \
39           if (error) \
40                     return (error); \
41 \
42           if (SCARG_COMPAT_PTR(uap, oss)) { \
43                     COMPAT_SET_PTR(css.ss_sp, oss.ss_sp); \
44                     css.ss_size = oss.ss_size; \
45                     if (ss_onstack == SS_ONSTACK && ss_disable == SS_DISABLE) \
46                               css.ss_flags = oss.ss_flags; \
47                     else \
48                               css.ss_flags = \
49                                   (oss.ss_flags & SS_ONSTACK ? ss_onstack : 0) \
50                                   | (oss.ss_flags & SS_DISABLE ? ss_disable : 0); \
51                     error = copyout(&css, SCARG_COMPAT_PTR(uap, oss), sizeof(css));\
52                     if (error) \
53                               return (error); \
54           } \
55           return (0); \
56 } while (0)
57