]> gcc.gnu.org Git - gcc.git/blame - libgcc/config/i386/sol2-unwind.h
Remove obsolete Solaris 9 support
[gcc.git] / libgcc / config / i386 / sol2-unwind.h
CommitLineData
8d232178 1/* DWARF2 EH unwinding support for AMD x86-64 and x86.
ac1dca3c 2 Copyright (C) 2009-2014 Free Software Foundation, Inc.
8d232178
OH
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
24
25/* Do code reading to identify a signal frame, and set the frame
26 state data appropriately. See unwind-dw2.c for the structs. */
27
28#include <ucontext.h>
ea2d8f12 29#include <sys/frame.h>
8d232178
OH
30
31#ifdef __x86_64__
32
33#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
34
35static _Unwind_Reason_Code
36x86_64_fallback_frame_state (struct _Unwind_Context *context,
37 _Unwind_FrameState *fs)
38{
39 unsigned char *pc = context->ra;
40 mcontext_t *mctx;
41 long new_cfa;
42
ea2d8f12 43 if (/* Solaris 10+
8d232178
OH
44 ------------
45 <__sighndlr+0>: push %rbp
46 <__sighndlr+1>: mov %rsp,%rbp
47 <__sighndlr+4>: callq *%rcx
48 <__sighndlr+6>: leaveq <--- PC
49 <__sighndlr+7>: retq */
50 *(unsigned long *)(pc - 6) == 0xc3c9d1ffe5894855)
ea2d8f12
RO
51
52 /* We need to move up three frames:
53
54 <signal handler> <-- context->cfa
55 __sighndlr
56 call_user_handler
57 sigacthandler
58 <kernel>
59
60 context->cfa points into the frame after the saved frame pointer and
61 saved pc (struct frame).
62
63 The ucontext_t structure is in the kernel frame after the signal
64 number and a siginfo_t *. Since the frame sizes vary even within
65 Solaris 10 updates, we need to walk the stack to get there. */
8d232178 66 {
ea2d8f12
RO
67 struct frame *fp = (struct frame *) context->cfa - 1;
68 struct handler_args {
69 int signo;
70 siginfo_t *sip;
71 ucontext_t ucontext;
72 } *handler_args;
73 ucontext_t *ucp;
74
75 /* Next frame: __sighndlr frame pointer. */
76 fp = (struct frame *) fp->fr_savfp;
77 /* call_user_handler frame pointer. */
78 fp = (struct frame *) fp->fr_savfp;
79 /* sigacthandler frame pointer. */
80 fp = (struct frame *) fp->fr_savfp;
81
82 /* The argument area precedes the struct frame. */
83 handler_args = (struct handler_args *) (fp + 1);
84 ucp = &handler_args->ucontext;
85 mctx = &ucp->uc_mcontext;
8d232178
OH
86 }
87 else
88 return _URC_END_OF_STACK;
89
90 new_cfa = mctx->gregs[REG_RSP];
91
92 fs->regs.cfa_how = CFA_REG_OFFSET;
93 fs->regs.cfa_reg = 7;
94 fs->regs.cfa_offset = new_cfa - (long) context->cfa;
95
96 /* The SVR4 register numbering macros aren't usable in libgcc. */
97 fs->regs.reg[0].how = REG_SAVED_OFFSET;
98 fs->regs.reg[0].loc.offset = (long)&mctx->gregs[REG_RAX] - new_cfa;
99 fs->regs.reg[1].how = REG_SAVED_OFFSET;
100 fs->regs.reg[1].loc.offset = (long)&mctx->gregs[REG_RDX] - new_cfa;
101 fs->regs.reg[2].how = REG_SAVED_OFFSET;
102 fs->regs.reg[2].loc.offset = (long)&mctx->gregs[REG_RCX] - new_cfa;
103 fs->regs.reg[3].how = REG_SAVED_OFFSET;
104 fs->regs.reg[3].loc.offset = (long)&mctx->gregs[REG_RBX] - new_cfa;
105 fs->regs.reg[4].how = REG_SAVED_OFFSET;
106 fs->regs.reg[4].loc.offset = (long)&mctx->gregs[REG_RSI] - new_cfa;
107 fs->regs.reg[5].how = REG_SAVED_OFFSET;
108 fs->regs.reg[5].loc.offset = (long)&mctx->gregs[REG_RDI] - new_cfa;
109 fs->regs.reg[6].how = REG_SAVED_OFFSET;
110 fs->regs.reg[6].loc.offset = (long)&mctx->gregs[REG_RBP] - new_cfa;
111 fs->regs.reg[8].how = REG_SAVED_OFFSET;
112 fs->regs.reg[8].loc.offset = (long)&mctx->gregs[REG_R8] - new_cfa;
113 fs->regs.reg[9].how = REG_SAVED_OFFSET;
114 fs->regs.reg[9].loc.offset = (long)&mctx->gregs[REG_R9] - new_cfa;
115 fs->regs.reg[10].how = REG_SAVED_OFFSET;
116 fs->regs.reg[10].loc.offset = (long)&mctx->gregs[REG_R10] - new_cfa;
117 fs->regs.reg[11].how = REG_SAVED_OFFSET;
118 fs->regs.reg[11].loc.offset = (long)&mctx->gregs[REG_R11] - new_cfa;
119 fs->regs.reg[12].how = REG_SAVED_OFFSET;
120 fs->regs.reg[12].loc.offset = (long)&mctx->gregs[REG_R12] - new_cfa;
121 fs->regs.reg[13].how = REG_SAVED_OFFSET;
122 fs->regs.reg[13].loc.offset = (long)&mctx->gregs[REG_R13] - new_cfa;
123 fs->regs.reg[14].how = REG_SAVED_OFFSET;
124 fs->regs.reg[14].loc.offset = (long)&mctx->gregs[REG_R14] - new_cfa;
125 fs->regs.reg[15].how = REG_SAVED_OFFSET;
126 fs->regs.reg[15].loc.offset = (long)&mctx->gregs[REG_R15] - new_cfa;
127 fs->regs.reg[16].how = REG_SAVED_OFFSET;
128 fs->regs.reg[16].loc.offset = (long)&mctx->gregs[REG_RIP] - new_cfa;
129 fs->retaddr_column = 16;
130 fs->signal_frame = 1;
131
132 return _URC_NO_REASON;
133}
134
135#else
136
137#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
138
139static _Unwind_Reason_Code
140x86_fallback_frame_state (struct _Unwind_Context *context,
141 _Unwind_FrameState *fs)
142{
143 unsigned char *pc = context->ra;
144 mcontext_t *mctx;
145 long new_cfa;
146
d9f069ab
RO
147 if (/* Solaris 10
148 -----------
8d232178
OH
149 <__sighndlr+0>: push %ebp
150 <__sighndlr+1>: mov %esp,%ebp
151 <__sighndlr+3>: pushl 0x10(%ebp)
152 <__sighndlr+6>: pushl 0xc(%ebp)
153 <__sighndlr+9>: pushl 0x8(%ebp)
154 <__sighndlr+12>: call *0x14(%ebp)
155 <__sighndlr+15>: add $0xc,%esp <--- PC
156 <__sighndlr+18>: leave
157 <__sighndlr+19>: ret */
158 (*(unsigned long *)(pc - 15) == 0xffec8b55
159 && *(unsigned long *)(pc - 11) == 0x75ff1075
160 && *(unsigned long *)(pc - 7) == 0x0875ff0c
161 && *(unsigned long *)(pc - 3) == 0x831455ff
ea2d8f12
RO
162 && *(unsigned long *)(pc + 1) == 0xc3c90cc4)
163
164 || /* Solaris 11 before snv_125
165 --------------------------
166 <__sighndlr+0> push %ebp
167 <__sighndlr+1> mov %esp,%ebp
168 <__sighndlr+4> pushl 0x10(%ebp)
169 <__sighndlr+6> pushl 0xc(%ebp)
170 <__sighndlr+9> pushl 0x8(%ebp)
171 <__sighndlr+12> call *0x14(%ebp)
172 <__sighndlr+15> add $0xc,%esp
173 <__sighndlr+18> leave <--- PC
174 <__sighndlr+19> ret */
175 (*(unsigned long *)(pc - 18) == 0xffec8b55
176 && *(unsigned long *)(pc - 14) == 0x7fff107f
177 && *(unsigned long *)(pc - 10) == 0x0875ff0c
178 && *(unsigned long *)(pc - 6) == 0x83145fff
179 && *(unsigned long *)(pc - 1) == 0xc3c90cc4)
180
181 || /* Solaris 11 since snv_125
182 -------------------------
183 <__sighndlr+0> push %ebp
184 <__sighndlr+1> mov %esp,%ebp
185 <__sighndlr+3> and $0xfffffff0,%esp
186 <__sighndlr+6> sub $0x4,%esp
187 <__sighndlr+9> pushl 0x10(%ebp)
188 <__sighndlr+12> pushl 0xc(%ebp)
189 <__sighndlr+15> pushl 0x8(%ebp)
190 <__sighndlr+18> call *0x14(%ebp)
191 <__sighndlr+21> leave <--- PC
192 <__sighndlr+22> ret */
193 (*(unsigned long *)(pc - 21) == 0x83ec8b55
194 && *(unsigned long *)(pc - 17) == 0xec83f0e4
195 && *(unsigned long *)(pc - 13) == 0x1075ff04
196 && *(unsigned long *)(pc - 9) == 0xff0c75ff
197 && *(unsigned long *)(pc - 5) == 0x55ff0875
198 && (*(unsigned long *)(pc - 1) & 0x00ffffff) == 0x00c3c914))
8d232178
OH
199 {
200 struct handler_args {
201 int signo;
202 siginfo_t *sip;
203 ucontext_t *ucontext;
204 } *handler_args = context->cfa;
205 mctx = &handler_args->ucontext->uc_mcontext;
206 }
207 else
208 return _URC_END_OF_STACK;
209
210 new_cfa = mctx->gregs[UESP];
211
212 fs->regs.cfa_how = CFA_REG_OFFSET;
213 fs->regs.cfa_reg = 4;
214 fs->regs.cfa_offset = new_cfa - (long) context->cfa;
215
216 /* The SVR4 register numbering macros aren't usable in libgcc. */
217 fs->regs.reg[0].how = REG_SAVED_OFFSET;
218 fs->regs.reg[0].loc.offset = (long)&mctx->gregs[EAX] - new_cfa;
219 fs->regs.reg[3].how = REG_SAVED_OFFSET;
220 fs->regs.reg[3].loc.offset = (long)&mctx->gregs[EBX] - new_cfa;
221 fs->regs.reg[1].how = REG_SAVED_OFFSET;
222 fs->regs.reg[1].loc.offset = (long)&mctx->gregs[ECX] - new_cfa;
223 fs->regs.reg[2].how = REG_SAVED_OFFSET;
224 fs->regs.reg[2].loc.offset = (long)&mctx->gregs[EDX] - new_cfa;
225 fs->regs.reg[6].how = REG_SAVED_OFFSET;
226 fs->regs.reg[6].loc.offset = (long)&mctx->gregs[ESI] - new_cfa;
227 fs->regs.reg[7].how = REG_SAVED_OFFSET;
228 fs->regs.reg[7].loc.offset = (long)&mctx->gregs[EDI] - new_cfa;
229 fs->regs.reg[5].how = REG_SAVED_OFFSET;
230 fs->regs.reg[5].loc.offset = (long)&mctx->gregs[EBP] - new_cfa;
231 fs->regs.reg[8].how = REG_SAVED_OFFSET;
232 fs->regs.reg[8].loc.offset = (long)&mctx->gregs[EIP] - new_cfa;
233 fs->retaddr_column = 8;
0ba045df
EB
234
235 /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn
236 rather than before it, so don't set fs->signal_frame in that case.
237 We test whether the ES field of the Status Register is zero. */
238 if ((mctx->fpregs.fp_reg_set.fpchip_state.status & 0x80) == 0)
239 fs->signal_frame = 1;
8d232178
OH
240
241 return _URC_NO_REASON;
242}
243
244#endif
This page took 0.826992 seconds and 5 git commands to generate.