Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/arch/arm/kernel/signal.c
0004  *
0005  *  Copyright (C) 1995-2009 Russell King
0006  */
0007 #include <linux/errno.h>
0008 #include <linux/random.h>
0009 #include <linux/signal.h>
0010 #include <linux/personality.h>
0011 #include <linux/uaccess.h>
0012 #include <linux/resume_user_mode.h>
0013 #include <linux/uprobes.h>
0014 #include <linux/syscalls.h>
0015 
0016 #include <asm/elf.h>
0017 #include <asm/cacheflush.h>
0018 #include <asm/traps.h>
0019 #include <asm/unistd.h>
0020 #include <asm/vfp.h>
0021 
0022 #include "signal.h"
0023 
0024 extern const unsigned long sigreturn_codes[17];
0025 
0026 static unsigned long signal_return_offset;
0027 
0028 #ifdef CONFIG_IWMMXT
0029 
0030 static int preserve_iwmmxt_context(struct iwmmxt_sigframe __user *frame)
0031 {
0032     char kbuf[sizeof(*frame) + 8];
0033     struct iwmmxt_sigframe *kframe;
0034     int err = 0;
0035 
0036     /* the iWMMXt context must be 64 bit aligned */
0037     kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
0038 
0039     if (test_thread_flag(TIF_USING_IWMMXT)) {
0040         kframe->magic = IWMMXT_MAGIC;
0041         kframe->size = IWMMXT_STORAGE_SIZE;
0042         iwmmxt_task_copy(current_thread_info(), &kframe->storage);
0043     } else {
0044         /*
0045          * For bug-compatibility with older kernels, some space
0046          * has to be reserved for iWMMXt even if it's not used.
0047          * Set the magic and size appropriately so that properly
0048          * written userspace can skip it reliably:
0049          */
0050         *kframe = (struct iwmmxt_sigframe) {
0051             .magic = DUMMY_MAGIC,
0052             .size  = IWMMXT_STORAGE_SIZE,
0053         };
0054     }
0055 
0056     err = __copy_to_user(frame, kframe, sizeof(*kframe));
0057 
0058     return err;
0059 }
0060 
0061 static int restore_iwmmxt_context(char __user **auxp)
0062 {
0063     struct iwmmxt_sigframe __user *frame =
0064         (struct iwmmxt_sigframe __user *)*auxp;
0065     char kbuf[sizeof(*frame) + 8];
0066     struct iwmmxt_sigframe *kframe;
0067 
0068     /* the iWMMXt context must be 64 bit aligned */
0069     kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
0070     if (__copy_from_user(kframe, frame, sizeof(*frame)))
0071         return -1;
0072 
0073     /*
0074      * For non-iWMMXt threads: a single iwmmxt_sigframe-sized dummy
0075      * block is discarded for compatibility with setup_sigframe() if
0076      * present, but we don't mandate its presence.  If some other
0077      * magic is here, it's not for us:
0078      */
0079     if (!test_thread_flag(TIF_USING_IWMMXT) &&
0080         kframe->magic != DUMMY_MAGIC)
0081         return 0;
0082 
0083     if (kframe->size != IWMMXT_STORAGE_SIZE)
0084         return -1;
0085 
0086     if (test_thread_flag(TIF_USING_IWMMXT)) {
0087         if (kframe->magic != IWMMXT_MAGIC)
0088             return -1;
0089 
0090         iwmmxt_task_restore(current_thread_info(), &kframe->storage);
0091     }
0092 
0093     *auxp += IWMMXT_STORAGE_SIZE;
0094     return 0;
0095 }
0096 
0097 #endif
0098 
0099 #ifdef CONFIG_VFP
0100 
0101 static int preserve_vfp_context(struct vfp_sigframe __user *frame)
0102 {
0103     struct vfp_sigframe kframe;
0104     int err = 0;
0105 
0106     memset(&kframe, 0, sizeof(kframe));
0107     kframe.magic = VFP_MAGIC;
0108     kframe.size = VFP_STORAGE_SIZE;
0109 
0110     err = vfp_preserve_user_clear_hwstate(&kframe.ufp, &kframe.ufp_exc);
0111     if (err)
0112         return err;
0113 
0114     return __copy_to_user(frame, &kframe, sizeof(kframe));
0115 }
0116 
0117 static int restore_vfp_context(char __user **auxp)
0118 {
0119     struct vfp_sigframe frame;
0120     int err;
0121 
0122     err = __copy_from_user(&frame, *auxp, sizeof(frame));
0123     if (err)
0124         return err;
0125 
0126     if (frame.magic != VFP_MAGIC || frame.size != VFP_STORAGE_SIZE)
0127         return -EINVAL;
0128 
0129     *auxp += sizeof(frame);
0130     return vfp_restore_user_hwstate(&frame.ufp, &frame.ufp_exc);
0131 }
0132 
0133 #endif
0134 
0135 /*
0136  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
0137  */
0138 
0139 static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
0140 {
0141     struct sigcontext context;
0142     char __user *aux;
0143     sigset_t set;
0144     int err;
0145 
0146     err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
0147     if (err == 0)
0148         set_current_blocked(&set);
0149 
0150     err |= __copy_from_user(&context, &sf->uc.uc_mcontext, sizeof(context));
0151     if (err == 0) {
0152         regs->ARM_r0 = context.arm_r0;
0153         regs->ARM_r1 = context.arm_r1;
0154         regs->ARM_r2 = context.arm_r2;
0155         regs->ARM_r3 = context.arm_r3;
0156         regs->ARM_r4 = context.arm_r4;
0157         regs->ARM_r5 = context.arm_r5;
0158         regs->ARM_r6 = context.arm_r6;
0159         regs->ARM_r7 = context.arm_r7;
0160         regs->ARM_r8 = context.arm_r8;
0161         regs->ARM_r9 = context.arm_r9;
0162         regs->ARM_r10 = context.arm_r10;
0163         regs->ARM_fp = context.arm_fp;
0164         regs->ARM_ip = context.arm_ip;
0165         regs->ARM_sp = context.arm_sp;
0166         regs->ARM_lr = context.arm_lr;
0167         regs->ARM_pc = context.arm_pc;
0168         regs->ARM_cpsr = context.arm_cpsr;
0169     }
0170 
0171     err |= !valid_user_regs(regs);
0172 
0173     aux = (char __user *) sf->uc.uc_regspace;
0174 #ifdef CONFIG_IWMMXT
0175     if (err == 0)
0176         err |= restore_iwmmxt_context(&aux);
0177 #endif
0178 #ifdef CONFIG_VFP
0179     if (err == 0)
0180         err |= restore_vfp_context(&aux);
0181 #endif
0182 
0183     return err;
0184 }
0185 
0186 asmlinkage int sys_sigreturn(struct pt_regs *regs)
0187 {
0188     struct sigframe __user *frame;
0189 
0190     /* Always make any pending restarted system calls return -EINTR */
0191     current->restart_block.fn = do_no_restart_syscall;
0192 
0193     /*
0194      * Since we stacked the signal on a 64-bit boundary,
0195      * then 'sp' should be word aligned here.  If it's
0196      * not, then the user is trying to mess with us.
0197      */
0198     if (regs->ARM_sp & 7)
0199         goto badframe;
0200 
0201     frame = (struct sigframe __user *)regs->ARM_sp;
0202 
0203     if (!access_ok(frame, sizeof (*frame)))
0204         goto badframe;
0205 
0206     if (restore_sigframe(regs, frame))
0207         goto badframe;
0208 
0209     return regs->ARM_r0;
0210 
0211 badframe:
0212     force_sig(SIGSEGV);
0213     return 0;
0214 }
0215 
0216 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
0217 {
0218     struct rt_sigframe __user *frame;
0219 
0220     /* Always make any pending restarted system calls return -EINTR */
0221     current->restart_block.fn = do_no_restart_syscall;
0222 
0223     /*
0224      * Since we stacked the signal on a 64-bit boundary,
0225      * then 'sp' should be word aligned here.  If it's
0226      * not, then the user is trying to mess with us.
0227      */
0228     if (regs->ARM_sp & 7)
0229         goto badframe;
0230 
0231     frame = (struct rt_sigframe __user *)regs->ARM_sp;
0232 
0233     if (!access_ok(frame, sizeof (*frame)))
0234         goto badframe;
0235 
0236     if (restore_sigframe(regs, &frame->sig))
0237         goto badframe;
0238 
0239     if (restore_altstack(&frame->sig.uc.uc_stack))
0240         goto badframe;
0241 
0242     return regs->ARM_r0;
0243 
0244 badframe:
0245     force_sig(SIGSEGV);
0246     return 0;
0247 }
0248 
0249 static int
0250 setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
0251 {
0252     struct aux_sigframe __user *aux;
0253     struct sigcontext context;
0254     int err = 0;
0255 
0256     context = (struct sigcontext) {
0257         .arm_r0        = regs->ARM_r0,
0258         .arm_r1        = regs->ARM_r1,
0259         .arm_r2        = regs->ARM_r2,
0260         .arm_r3        = regs->ARM_r3,
0261         .arm_r4        = regs->ARM_r4,
0262         .arm_r5        = regs->ARM_r5,
0263         .arm_r6        = regs->ARM_r6,
0264         .arm_r7        = regs->ARM_r7,
0265         .arm_r8        = regs->ARM_r8,
0266         .arm_r9        = regs->ARM_r9,
0267         .arm_r10       = regs->ARM_r10,
0268         .arm_fp        = regs->ARM_fp,
0269         .arm_ip        = regs->ARM_ip,
0270         .arm_sp        = regs->ARM_sp,
0271         .arm_lr        = regs->ARM_lr,
0272         .arm_pc        = regs->ARM_pc,
0273         .arm_cpsr      = regs->ARM_cpsr,
0274 
0275         .trap_no       = current->thread.trap_no,
0276         .error_code    = current->thread.error_code,
0277         .fault_address = current->thread.address,
0278         .oldmask       = set->sig[0],
0279     };
0280 
0281     err |= __copy_to_user(&sf->uc.uc_mcontext, &context, sizeof(context));
0282 
0283     err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
0284 
0285     aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
0286 #ifdef CONFIG_IWMMXT
0287     if (err == 0)
0288         err |= preserve_iwmmxt_context(&aux->iwmmxt);
0289 #endif
0290 #ifdef CONFIG_VFP
0291     if (err == 0)
0292         err |= preserve_vfp_context(&aux->vfp);
0293 #endif
0294     err |= __put_user(0, &aux->end_magic);
0295 
0296     return err;
0297 }
0298 
0299 static inline void __user *
0300 get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize)
0301 {
0302     unsigned long sp = sigsp(regs->ARM_sp, ksig);
0303     void __user *frame;
0304 
0305     /*
0306      * ATPCS B01 mandates 8-byte alignment
0307      */
0308     frame = (void __user *)((sp - framesize) & ~7);
0309 
0310     /*
0311      * Check that we can actually write to the signal frame.
0312      */
0313     if (!access_ok(frame, framesize))
0314         frame = NULL;
0315 
0316     return frame;
0317 }
0318 
0319 static int
0320 setup_return(struct pt_regs *regs, struct ksignal *ksig,
0321          unsigned long __user *rc, void __user *frame)
0322 {
0323     unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler;
0324     unsigned long handler_fdpic_GOT = 0;
0325     unsigned long retcode;
0326     unsigned int idx, thumb = 0;
0327     unsigned long cpsr = regs->ARM_cpsr & ~(PSR_f | PSR_E_BIT);
0328     bool fdpic = IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC) &&
0329              (current->personality & FDPIC_FUNCPTRS);
0330 
0331     if (fdpic) {
0332         unsigned long __user *fdpic_func_desc =
0333                     (unsigned long __user *)handler;
0334         if (__get_user(handler, &fdpic_func_desc[0]) ||
0335             __get_user(handler_fdpic_GOT, &fdpic_func_desc[1]))
0336             return 1;
0337     }
0338 
0339     cpsr |= PSR_ENDSTATE;
0340 
0341     /*
0342      * Maybe we need to deliver a 32-bit signal to a 26-bit task.
0343      */
0344     if (ksig->ka.sa.sa_flags & SA_THIRTYTWO)
0345         cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
0346 
0347 #ifdef CONFIG_ARM_THUMB
0348     if (elf_hwcap & HWCAP_THUMB) {
0349         /*
0350          * The LSB of the handler determines if we're going to
0351          * be using THUMB or ARM mode for this signal handler.
0352          */
0353         thumb = handler & 1;
0354 
0355         /*
0356          * Clear the If-Then Thumb-2 execution state.  ARM spec
0357          * requires this to be all 000s in ARM mode.  Snapdragon
0358          * S4/Krait misbehaves on a Thumb=>ARM signal transition
0359          * without this.
0360          *
0361          * We must do this whenever we are running on a Thumb-2
0362          * capable CPU, which includes ARMv6T2.  However, we elect
0363          * to always do this to simplify the code; this field is
0364          * marked UNK/SBZP for older architectures.
0365          */
0366         cpsr &= ~PSR_IT_MASK;
0367 
0368         if (thumb) {
0369             cpsr |= PSR_T_BIT;
0370         } else
0371             cpsr &= ~PSR_T_BIT;
0372     }
0373 #endif
0374 
0375     if (ksig->ka.sa.sa_flags & SA_RESTORER) {
0376         retcode = (unsigned long)ksig->ka.sa.sa_restorer;
0377         if (fdpic) {
0378             /*
0379              * We need code to load the function descriptor.
0380              * That code follows the standard sigreturn code
0381              * (6 words), and is made of 3 + 2 words for each
0382              * variant. The 4th copied word is the actual FD
0383              * address that the assembly code expects.
0384              */
0385             idx = 6 + thumb * 3;
0386             if (ksig->ka.sa.sa_flags & SA_SIGINFO)
0387                 idx += 5;
0388             if (__put_user(sigreturn_codes[idx],   rc  ) ||
0389                 __put_user(sigreturn_codes[idx+1], rc+1) ||
0390                 __put_user(sigreturn_codes[idx+2], rc+2) ||
0391                 __put_user(retcode,                rc+3))
0392                 return 1;
0393             goto rc_finish;
0394         }
0395     } else {
0396         idx = thumb << 1;
0397         if (ksig->ka.sa.sa_flags & SA_SIGINFO)
0398             idx += 3;
0399 
0400         /*
0401          * Put the sigreturn code on the stack no matter which return
0402          * mechanism we use in order to remain ABI compliant
0403          */
0404         if (__put_user(sigreturn_codes[idx],   rc) ||
0405             __put_user(sigreturn_codes[idx+1], rc+1))
0406             return 1;
0407 
0408 rc_finish:
0409 #ifdef CONFIG_MMU
0410         if (cpsr & MODE32_BIT) {
0411             struct mm_struct *mm = current->mm;
0412 
0413             /*
0414              * 32-bit code can use the signal return page
0415              * except when the MPU has protected the vectors
0416              * page from PL0
0417              */
0418             retcode = mm->context.sigpage + signal_return_offset +
0419                   (idx << 2) + thumb;
0420         } else
0421 #endif
0422         {
0423             /*
0424              * Ensure that the instruction cache sees
0425              * the return code written onto the stack.
0426              */
0427             flush_icache_range((unsigned long)rc,
0428                        (unsigned long)(rc + 3));
0429 
0430             retcode = ((unsigned long)rc) + thumb;
0431         }
0432     }
0433 
0434     regs->ARM_r0 = ksig->sig;
0435     regs->ARM_sp = (unsigned long)frame;
0436     regs->ARM_lr = retcode;
0437     regs->ARM_pc = handler;
0438     if (fdpic)
0439         regs->ARM_r9 = handler_fdpic_GOT;
0440     regs->ARM_cpsr = cpsr;
0441 
0442     return 0;
0443 }
0444 
0445 static int
0446 setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
0447 {
0448     struct sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame));
0449     int err = 0;
0450 
0451     if (!frame)
0452         return 1;
0453 
0454     /*
0455      * Set uc.uc_flags to a value which sc.trap_no would never have.
0456      */
0457     err = __put_user(0x5ac3c35a, &frame->uc.uc_flags);
0458 
0459     err |= setup_sigframe(frame, regs, set);
0460     if (err == 0)
0461         err = setup_return(regs, ksig, frame->retcode, frame);
0462 
0463     return err;
0464 }
0465 
0466 static int
0467 setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
0468 {
0469     struct rt_sigframe __user *frame = get_sigframe(ksig, regs, sizeof(*frame));
0470     int err = 0;
0471 
0472     if (!frame)
0473         return 1;
0474 
0475     err |= copy_siginfo_to_user(&frame->info, &ksig->info);
0476 
0477     err |= __put_user(0, &frame->sig.uc.uc_flags);
0478     err |= __put_user(NULL, &frame->sig.uc.uc_link);
0479 
0480     err |= __save_altstack(&frame->sig.uc.uc_stack, regs->ARM_sp);
0481     err |= setup_sigframe(&frame->sig, regs, set);
0482     if (err == 0)
0483         err = setup_return(regs, ksig, frame->sig.retcode, frame);
0484 
0485     if (err == 0) {
0486         /*
0487          * For realtime signals we must also set the second and third
0488          * arguments for the signal handler.
0489          *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
0490          */
0491         regs->ARM_r1 = (unsigned long)&frame->info;
0492         regs->ARM_r2 = (unsigned long)&frame->sig.uc;
0493     }
0494 
0495     return err;
0496 }
0497 
0498 /*
0499  * OK, we're invoking a handler
0500  */ 
0501 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
0502 {
0503     sigset_t *oldset = sigmask_to_save();
0504     int ret;
0505 
0506     /*
0507      * Perform fixup for the pre-signal frame.
0508      */
0509     rseq_signal_deliver(ksig, regs);
0510 
0511     /*
0512      * Set up the stack frame
0513      */
0514     if (ksig->ka.sa.sa_flags & SA_SIGINFO)
0515         ret = setup_rt_frame(ksig, oldset, regs);
0516     else
0517         ret = setup_frame(ksig, oldset, regs);
0518 
0519     /*
0520      * Check that the resulting registers are actually sane.
0521      */
0522     ret |= !valid_user_regs(regs);
0523 
0524     signal_setup_done(ret, ksig, 0);
0525 }
0526 
0527 /*
0528  * Note that 'init' is a special process: it doesn't get signals it doesn't
0529  * want to handle. Thus you cannot kill init even with a SIGKILL even by
0530  * mistake.
0531  *
0532  * Note that we go through the signals twice: once to check the signals that
0533  * the kernel can handle, and then we build all the user-level signal handling
0534  * stack-frames in one go after that.
0535  */
0536 static int do_signal(struct pt_regs *regs, int syscall)
0537 {
0538     unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
0539     struct ksignal ksig;
0540     int restart = 0;
0541 
0542     /*
0543      * If we were from a system call, check for system call restarting...
0544      */
0545     if (syscall) {
0546         continue_addr = regs->ARM_pc;
0547         restart_addr = continue_addr - (thumb_mode(regs) ? 2 : 4);
0548         retval = regs->ARM_r0;
0549 
0550         /*
0551          * Prepare for system call restart.  We do this here so that a
0552          * debugger will see the already changed PSW.
0553          */
0554         switch (retval) {
0555         case -ERESTART_RESTARTBLOCK:
0556             restart -= 2;
0557             fallthrough;
0558         case -ERESTARTNOHAND:
0559         case -ERESTARTSYS:
0560         case -ERESTARTNOINTR:
0561             restart++;
0562             regs->ARM_r0 = regs->ARM_ORIG_r0;
0563             regs->ARM_pc = restart_addr;
0564             break;
0565         }
0566     }
0567 
0568     /*
0569      * Get the signal to deliver.  When running under ptrace, at this
0570      * point the debugger may change all our registers ...
0571      */
0572     /*
0573      * Depending on the signal settings we may need to revert the
0574      * decision to restart the system call.  But skip this if a
0575      * debugger has chosen to restart at a different PC.
0576      */
0577     if (get_signal(&ksig)) {
0578         /* handler */
0579         if (unlikely(restart) && regs->ARM_pc == restart_addr) {
0580             if (retval == -ERESTARTNOHAND ||
0581                 retval == -ERESTART_RESTARTBLOCK
0582                 || (retval == -ERESTARTSYS
0583                 && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
0584                 regs->ARM_r0 = -EINTR;
0585                 regs->ARM_pc = continue_addr;
0586             }
0587         }
0588         handle_signal(&ksig, regs);
0589     } else {
0590         /* no handler */
0591         restore_saved_sigmask();
0592         if (unlikely(restart) && regs->ARM_pc == restart_addr) {
0593             regs->ARM_pc = continue_addr;
0594             return restart;
0595         }
0596     }
0597     return 0;
0598 }
0599 
0600 asmlinkage int
0601 do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
0602 {
0603     /*
0604      * The assembly code enters us with IRQs off, but it hasn't
0605      * informed the tracing code of that for efficiency reasons.
0606      * Update the trace code with the current status.
0607      */
0608     trace_hardirqs_off();
0609     do {
0610         if (likely(thread_flags & _TIF_NEED_RESCHED)) {
0611             schedule();
0612         } else {
0613             if (unlikely(!user_mode(regs)))
0614                 return 0;
0615             local_irq_enable();
0616             if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
0617                 int restart = do_signal(regs, syscall);
0618                 if (unlikely(restart)) {
0619                     /*
0620                      * Restart without handlers.
0621                      * Deal with it without leaving
0622                      * the kernel space.
0623                      */
0624                     return restart;
0625                 }
0626                 syscall = 0;
0627             } else if (thread_flags & _TIF_UPROBE) {
0628                 uprobe_notify_resume(regs);
0629             } else {
0630                 resume_user_mode_work(regs);
0631             }
0632         }
0633         local_irq_disable();
0634         thread_flags = read_thread_flags();
0635     } while (thread_flags & _TIF_WORK_MASK);
0636     return 0;
0637 }
0638 
0639 struct page *get_signal_page(void)
0640 {
0641     unsigned long ptr;
0642     unsigned offset;
0643     struct page *page;
0644     void *addr;
0645 
0646     page = alloc_pages(GFP_KERNEL, 0);
0647 
0648     if (!page)
0649         return NULL;
0650 
0651     addr = page_address(page);
0652 
0653     /* Poison the entire page */
0654     memset32(addr, __opcode_to_mem_arm(0xe7fddef1),
0655          PAGE_SIZE / sizeof(u32));
0656 
0657     /* Give the signal return code some randomness */
0658     offset = 0x200 + (get_random_int() & 0x7fc);
0659     signal_return_offset = offset;
0660 
0661     /* Copy signal return handlers into the page */
0662     memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
0663 
0664     /* Flush out all instructions in this page */
0665     ptr = (unsigned long)addr;
0666     flush_icache_range(ptr, ptr + PAGE_SIZE);
0667 
0668     return page;
0669 }
0670 
0671 #ifdef CONFIG_DEBUG_RSEQ
0672 asmlinkage void do_rseq_syscall(struct pt_regs *regs)
0673 {
0674     rseq_syscall(regs);
0675 }
0676 #endif
0677 
0678 /*
0679  * Compile-time assertions for siginfo_t offsets. Check NSIG* as well, as
0680  * changes likely come with new fields that should be added below.
0681  */
0682 static_assert(NSIGILL   == 11);
0683 static_assert(NSIGFPE   == 15);
0684 static_assert(NSIGSEGV  == 9);
0685 static_assert(NSIGBUS   == 5);
0686 static_assert(NSIGTRAP  == 6);
0687 static_assert(NSIGCHLD  == 6);
0688 static_assert(NSIGSYS   == 2);
0689 static_assert(sizeof(siginfo_t) == 128);
0690 static_assert(__alignof__(siginfo_t) == 4);
0691 static_assert(offsetof(siginfo_t, si_signo) == 0x00);
0692 static_assert(offsetof(siginfo_t, si_errno) == 0x04);
0693 static_assert(offsetof(siginfo_t, si_code)  == 0x08);
0694 static_assert(offsetof(siginfo_t, si_pid)   == 0x0c);
0695 static_assert(offsetof(siginfo_t, si_uid)   == 0x10);
0696 static_assert(offsetof(siginfo_t, si_tid)   == 0x0c);
0697 static_assert(offsetof(siginfo_t, si_overrun)   == 0x10);
0698 static_assert(offsetof(siginfo_t, si_status)    == 0x14);
0699 static_assert(offsetof(siginfo_t, si_utime) == 0x18);
0700 static_assert(offsetof(siginfo_t, si_stime) == 0x1c);
0701 static_assert(offsetof(siginfo_t, si_value) == 0x14);
0702 static_assert(offsetof(siginfo_t, si_int)   == 0x14);
0703 static_assert(offsetof(siginfo_t, si_ptr)   == 0x14);
0704 static_assert(offsetof(siginfo_t, si_addr)  == 0x0c);
0705 static_assert(offsetof(siginfo_t, si_addr_lsb)  == 0x10);
0706 static_assert(offsetof(siginfo_t, si_lower) == 0x14);
0707 static_assert(offsetof(siginfo_t, si_upper) == 0x18);
0708 static_assert(offsetof(siginfo_t, si_pkey)  == 0x14);
0709 static_assert(offsetof(siginfo_t, si_perf_data) == 0x10);
0710 static_assert(offsetof(siginfo_t, si_perf_type) == 0x14);
0711 static_assert(offsetof(siginfo_t, si_perf_flags) == 0x18);
0712 static_assert(offsetof(siginfo_t, si_band)  == 0x0c);
0713 static_assert(offsetof(siginfo_t, si_fd)    == 0x10);
0714 static_assert(offsetof(siginfo_t, si_call_addr) == 0x0c);
0715 static_assert(offsetof(siginfo_t, si_syscall)   == 0x10);
0716 static_assert(offsetof(siginfo_t, si_arch)  == 0x14);