5 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
8 Desc: Macros to handle unix signals, x86_64 version.
12 #include <aros/x86_64/cpucontext.h>
14 #ifdef __AROS_EXEC_LIBRARY__
17 typedef struct ucontext regs_t
;
21 /* There's no need for USE_SA_SIGINFO, as we always use SA_SIGINFO
22 on x86_64 - there's no other sane way to get ucontext. */
23 #define SIGCORE_NEED_SA_SIGINFO 1
25 /* Make _GNU_SOURCE work */
27 /* We want to use some predefined register names */
38 #ifndef __KERNEL_STRICT_NAMES
39 #define __KERNEL_STRICT_NAMES
41 #include <bits/sigcontext.h>
43 typedef ucontext_t regs_t
;
45 /* name and type of the signal handler */
46 #define SIGHANDLER linux_sighandler
47 #define SIGHANDLER_T __sighandler_t
50 This macro contains some magic necessary to make it work.
51 The problem is that Linux offers no official way to obtain the
52 signals' context. Linux stores the signals' context on the
53 process' stack. It looks like this:
54 Attention: As of version 2.2 of the Linux kernel there is
55 not enough room on the stack anymore to save
56 any registers on it. So everything has to go into
57 the context structure. Previously PC and FP used
58 to be saved on the stack but now this would over-
59 write some return address.
60 The stack you see below is the stack of the last
61 active task within AROS. The linux kernel puts
62 all kinds of other junk on it.
65 +--------------------------+
66 | last entry before signal |
67 +--------------------------+
69 +--------------------------+
71 +--------------------------+
73 +--------------------------+
76 so the address of the signal context is &sig+1.
78 Well, we use the SIGCORE_NEED_SA_SIGINFO approach, so part of
79 the above is only kept for historical reasons.
82 #define GLOBAL_SIGNAL_INIT(sighandler) \
83 static void sighandler ## _gate (int sig, siginfo_t *blub, void *u) \
89 Macros to access the stack pointer, frame pointer and program
90 counter. The FP is the base address for accesses to arguments
91 and local variables of a function and PC is the current address
95 #define SP(uc) ((uc)->uc_mcontext.gregs[REG_RSP])
96 #define FP(uc) ((uc)->uc_mcontext.gregs[REG_RBP])
97 #define PC(uc) ((uc)->uc_mcontext.gregs[REG_RIP])
100 Macros to enable or disable all signals after the signal handler
101 has returned and the normal execution commences.
103 On Linux x86-64 signal mask is restored from uc_sigmask field of ucontext
106 #define SC_DISABLE(uc) uc->uc_sigmask = KernelBase->kb_PlatformData->sig_int_mask
107 #define SC_ENABLE(uc) pd->iface->SigEmptySet(&uc->uc_sigmask)
110 The names of the general purpose registers which are to be saved.
111 Use R and a number as name, no matter what the real name is.
112 General purpose registers (GPRs) are registers which can be
113 modified by the task (ie. data and address registers) and which are
114 not saved by the CPU when an interrupt happens.
116 #define R0(uc) ((uc)->uc_mcontext.gregs[REG_RAX])
117 #define R1(uc) ((uc)->uc_mcontext.gregs[REG_RBX])
118 #define R2(uc) ((uc)->uc_mcontext.gregs[REG_RCX])
119 #define R3(uc) ((uc)->uc_mcontext.gregs[REG_RDX])
120 #define R4(uc) ((uc)->uc_mcontext.gregs[REG_RDI])
121 #define R5(uc) ((uc)->uc_mcontext.gregs[REG_RSI])
122 #define R6(uc) ((uc)->uc_mcontext.gregs[REG_EFL])
123 #define R8(uc) ((uc)->uc_mcontext.gregs[REG_R8])
124 #define R9(uc) ((uc)->uc_mcontext.gregs[REG_R9])
125 #define R10(uc) ((uc)->uc_mcontext.gregs[REG_R10])
126 #define R11(uc) ((uc)->uc_mcontext.gregs[REG_R11])
127 #define R12(uc) ((uc)->uc_mcontext.gregs[REG_R12])
128 #define R13(uc) ((uc)->uc_mcontext.gregs[REG_R13])
129 #define R14(uc) ((uc)->uc_mcontext.gregs[REG_R14])
130 #define R15(uc) ((uc)->uc_mcontext.gregs[REG_R15])
133 Save and restore the CPU GPRs in the CPU context
135 #define SAVE_CPU(cc, sc) \
142 cc.rflags = R6(sc); \
156 * Restore CPU registers.
157 * Note that we do not restore segment registers because they
158 * are of own use by Linux.
160 #define RESTORE_CPU(cc, sc) \
167 R6(sc) = cc.rflags; \
181 * Save all registers from UNIX signal context to AROS context.
182 * Save also SSE state if the context has buffer. ECF_FPX will be set
183 * if SSE state was copied.
185 #define SAVEREGS(cc, sc) \
186 SAVE_CPU((cc)->regs, sc); \
187 if (sc->uc_mcontext.fpregs && (cc)->regs.FXData) \
189 (cc)->regs.Flags |= ECF_FPX; \
190 CopyMemQuick(sc->uc_mcontext.fpregs, (cc)->regs.FXData, sizeof(struct FPXContext)); \
194 * Restore all registers from AROS context to UNIX signal context.
195 * Check context flags to decide whether to restore SSE or not.
197 #define RESTOREREGS(cc, sc) \
198 RESTORE_CPU((cc)->regs, sc); \
199 if ((cc)->regs.Flags & ECF_FPX) \
200 CopyMemQuick((cc)->regs.FXData, sc->uc_mcontext.fpregs, sizeof(struct FPXContext));
202 /* Print signal context. Used in crash handler. */
203 #define PRINT_SC(sc) \
204 bug (" RSP=%016lx RBP=%016lx RIP=%016lx\n" \
205 " RAX=%016lx RBX=%016lx RCX=%016lx RDX=%016lx\n" \
206 " RDI=%016lx RSI=%016lx RFLAGS=%016lx\n" \
207 " R8 =%016lx R9 =%016lx R10=%016lx R11=%016lx\n" \
208 " R12=%016lx R13=%016lx R14=%016lx R15=%016lx\n" \
209 , SP(sc), FP(sc), PC(sc) \
210 , R0(sc), R1(sc), R2(sc), R3(sc) \
211 , R4(sc), R5(sc), R6(sc), R8(sc), R9(sc) \
212 , R10(sc), R11(sc), R12(sc), R13(sc), R14(sc), R15(sc) \
215 #endif /* __AROS_EXEC_LIBRARY__ */
217 #define EXCEPTIONS_COUNT 17
220 /* Use this structure to save/restore registers */
221 struct AROSCPUContext
223 struct ExceptionContext regs
;
227 #endif /* _SIGCORE_H */