Changeset View
Standalone View
sys/amd64/linux/linux.h
Show First 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
struct l_ucontext { | struct l_ucontext { | ||||
l_ulong uc_flags; | l_ulong uc_flags; | ||||
l_uintptr_t uc_link; | l_uintptr_t uc_link; | ||||
l_stack_t uc_stack; | l_stack_t uc_stack; | ||||
struct l_sigcontext uc_mcontext; | struct l_sigcontext uc_mcontext; | ||||
l_sigset_t uc_sigmask; | l_sigset_t uc_sigmask; | ||||
struct l_fpstate uc_fpregs; | |||||
kib: https://github.com/torvalds/linux/blob/6e0567b7305209c2d689ce57180a63d8dc657ad8/arch/x86/kernel… | |||||
Done Inline ActionsThe reason I wanted to avoid that is that this essentially requires Linux-specific variant of {get,set}_fpcontext(). Or are you thinking of some other way? trasz: The reason I wanted to avoid that is that this essentially requires Linux-specific variant of… | |||||
Not Done Inline ActionsIt is not, I believe (I did not do experiments to say it definitely). Their save area is compatible with ours, they just align it. kib: It is not, I believe (I did not do experiments to say it definitely). Their save area is… | |||||
Done Inline ActionsSo, I've just looked again into this, and I don't think this is practical. We can't copy FPU context from native mcontext_t into l_sigcontext, because there's no room: l_sigcontext only contains a pointer to FPU data (pointer to fpstate), not fpstate itself; looks like Linux simply puts the FPU data on the stack after l_ucontext: https://github.com/torvalds/linux/blob/6e0567b7305209c2d689ce57180a63d8dc657ad8/arch/x86/kernel/signal.c#L192. From what I understand, the whole idea of xsave is that its length is not fixed, so what's the problem with stashing our native mcontext_t there? trasz: So, I've just looked again into this, and I don't think this is practical. We can't copy FPU… | |||||
Not Done Inline ActionsThere is so called fixed area in XSAVE area that contains always present x87 FPU registers, and %XMM and related SSE2 state. Linux ucontext provides fixed locations for these registers: typedef struct ucontext_t { unsigned long int __ctx(uc_flags); struct ucontext_t *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; sigset_t uc_sigmask; struct _libc_fpstate __fpregs_mem; __extension__ unsigned long long int __ssp[4]; } ucontext_t; And typedef struct { gregset_t __ctx(gregs); /* Note that fpregs is a pointer. */ fpregset_t __ctx(fpregs); __extension__ unsigned long long __reserved1 [8]; } mcontext_t; struct _libc_fpstate { /* 64-bit FXSAVE format. */ __uint16_t __ctx(cwd); __uint16_t __ctx(swd); __uint16_t __ctx(ftw); __uint16_t __ctx(fop); __uint64_t __ctx(rip); __uint64_t __ctx(rdp); __uint32_t __ctx(mxcsr); __uint32_t __ctx(mxcr_mask); struct _libc_fpxreg _st[8]; struct _libc_xmmreg _xmm[16]; __uint32_t __glibc_reserved1[24]; }; I just looked into the filled context: uc->uc_mcontext.fpregs points to uc->__fpregs_mem.mxcsr. _libc_fpstate.st[] are x87 %st registers. _libc_fpstate._xmm are %xmm registers. Basically you need to copy the same names from our fpusave area to linux' one. This is ignoring XSAVE, i.e. AVX and larger extensiones. Lets do the FXSAVE right first. kib: There is so called fixed area in XSAVE area that contains always present x87 FPU registers, and… | |||||
}; | }; | ||||
#define LINUX_SI_PREAMBLE_SIZE (4 * sizeof(int)) | #define LINUX_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||||
#define LINUX_SI_MAX_SIZE 128 | #define LINUX_SI_MAX_SIZE 128 | ||||
#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE - \ | #define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE - \ | ||||
LINUX_SI_PREAMBLE_SIZE) / sizeof(l_int)) | LINUX_SI_PREAMBLE_SIZE) / sizeof(l_int)) | ||||
typedef union l_sigval { | typedef union l_sigval { | ||||
l_int sival_int; | l_int sival_int; | ||||
▲ Show 20 Lines • Show All 229 Lines • Show Last 20 Lines |
https://github.com/torvalds/linux/blob/6e0567b7305209c2d689ce57180a63d8dc657ad8/arch/x86/kernel/signal.c#L707
This is how signal frame for amd64 is described in the Linux sources comment, and it seems, after, some reading, indeed matching the code. Instead of corrupting l_ucontext definition, please implement it properly. In essence, the key part is the alignment/padding between ucontext and start of the fpu save area (our and Linux' should be compatible).