forked from Minki/linux
bbe6c77857
Up until now, the SH version of the sigcontext structure, and thus mcontext_t/ucontext_t, varied depending on the cpu model the kernel was built to run on. SH-4 (including SH-4A) and SH-2A used the form with space for FPU registers, and everything else used a form that omitted them. From a userspace perspective, however, the structure layout must be fixed for a given ABI. Traditionally glibc and uClibc used the form with space for FPU registers only when __SH4__ (which implies FPU; __SH4_NOFPU__ is the predefined macro for SH-4 but with no-FPU ABI) was defined. As a result: - SH-4 no-FPU programs never matched kernel sigcontext. - SH-3 programs did not match kernel sigcontext if run on SH-4, despite an apparent intent that they be compatible. - SH-2 and SH-2A programs (using uClibc) did not match kernel sigcontext if run on SH-2A. The mismatch might seem inconsequential because it occurs at the end of the sigcontext structure, but sigcontext is embedded as uc_mcontext in ucontext_t, where it is followed by uc_sigmask, an important member for signal handlers to have access to. In particular, access to uc_sigmask is necessary for a correct implementation of thread cancellation. It would be possible to retain support for both sigcontext ABIs via a personality mechanism, but since many configurations were already broken and nobody noticed, and since there are very few if any users of legacy no-FPU models anymore, I have opted to just remove the variation and always include space for the FPU registers in sigcontext. This was proposed and discussed on a thread "SH sigcontext ABI is broken" cross-posted to linux-sh, libc-alpha, and musl libc lists in June 2015, and no objections were raised. Signed-off-by: Rich Felker <dalias@libc.org>
38 lines
796 B
C
38 lines
796 B
C
#ifndef __ASM_SH_SIGCONTEXT_H
|
|
#define __ASM_SH_SIGCONTEXT_H
|
|
|
|
struct sigcontext {
|
|
unsigned long oldmask;
|
|
|
|
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
|
|
/* CPU registers */
|
|
unsigned long long sc_regs[63];
|
|
unsigned long long sc_tregs[8];
|
|
unsigned long long sc_pc;
|
|
unsigned long long sc_sr;
|
|
|
|
/* FPU registers */
|
|
unsigned long long sc_fpregs[32];
|
|
unsigned int sc_fpscr;
|
|
unsigned int sc_fpvalid;
|
|
#else
|
|
/* CPU registers */
|
|
unsigned long sc_regs[16];
|
|
unsigned long sc_pc;
|
|
unsigned long sc_pr;
|
|
unsigned long sc_sr;
|
|
unsigned long sc_gbr;
|
|
unsigned long sc_mach;
|
|
unsigned long sc_macl;
|
|
|
|
/* FPU registers */
|
|
unsigned long sc_fpregs[16];
|
|
unsigned long sc_xfpregs[16];
|
|
unsigned int sc_fpscr;
|
|
unsigned int sc_fpul;
|
|
unsigned int sc_ownedfp;
|
|
#endif
|
|
};
|
|
|
|
#endif /* __ASM_SH_SIGCONTEXT_H */
|