Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/i386/sol2-unwind.h @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* DWARF2 EH unwinding support for AMD x86-64 and x86. | |
2 Copyright (C) 2009 Free Software Foundation, Inc. | |
3 | |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 3, or (at your option) | |
9 any later version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 Under Section 7 of GPL version 3, you are granted additional | |
17 permissions described in the GCC Runtime Library Exception, version | |
18 3.1, as published by the Free Software Foundation. | |
19 | |
20 You should have received a copy of the GNU General Public License and | |
21 a copy of the GCC Runtime Library Exception along with this program; | |
22 see 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> | |
29 | |
30 #ifdef __x86_64__ | |
31 | |
32 #define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state | |
33 | |
34 static _Unwind_Reason_Code | |
35 x86_64_fallback_frame_state (struct _Unwind_Context *context, | |
36 _Unwind_FrameState *fs) | |
37 { | |
38 unsigned char *pc = context->ra; | |
39 mcontext_t *mctx; | |
40 long new_cfa; | |
41 | |
42 if (/* Solaris 2.10 | |
43 ------------ | |
44 <__sighndlr+0>: push %rbp | |
45 <__sighndlr+1>: mov %rsp,%rbp | |
46 <__sighndlr+4>: callq *%rcx | |
47 <__sighndlr+6>: leaveq <--- PC | |
48 <__sighndlr+7>: retq */ | |
49 *(unsigned long *)(pc - 6) == 0xc3c9d1ffe5894855) | |
50 /* We need to move up four frames (the kernel frame, the signal frame, | |
51 the call_user_handler frame and the __sighndlr frame). Two of them | |
52 have the minimum stack frame size (kernel and __sighndlr frames), | |
53 the signal frame has a stack frame size of 32 and there is another | |
54 with a stack frame size of 112 bytes (the call_user_handler frame). | |
55 The ucontext_t structure is after this offset. */ | |
56 { | |
57 int off = 16 + 16 + 32 + 112; | |
58 mctx = &((ucontext_t *) (context->cfa + off))->uc_mcontext; | |
59 } | |
60 else | |
61 return _URC_END_OF_STACK; | |
62 | |
63 new_cfa = mctx->gregs[REG_RSP]; | |
64 | |
65 fs->regs.cfa_how = CFA_REG_OFFSET; | |
66 fs->regs.cfa_reg = 7; | |
67 fs->regs.cfa_offset = new_cfa - (long) context->cfa; | |
68 | |
69 /* The SVR4 register numbering macros aren't usable in libgcc. */ | |
70 fs->regs.reg[0].how = REG_SAVED_OFFSET; | |
71 fs->regs.reg[0].loc.offset = (long)&mctx->gregs[REG_RAX] - new_cfa; | |
72 fs->regs.reg[1].how = REG_SAVED_OFFSET; | |
73 fs->regs.reg[1].loc.offset = (long)&mctx->gregs[REG_RDX] - new_cfa; | |
74 fs->regs.reg[2].how = REG_SAVED_OFFSET; | |
75 fs->regs.reg[2].loc.offset = (long)&mctx->gregs[REG_RCX] - new_cfa; | |
76 fs->regs.reg[3].how = REG_SAVED_OFFSET; | |
77 fs->regs.reg[3].loc.offset = (long)&mctx->gregs[REG_RBX] - new_cfa; | |
78 fs->regs.reg[4].how = REG_SAVED_OFFSET; | |
79 fs->regs.reg[4].loc.offset = (long)&mctx->gregs[REG_RSI] - new_cfa; | |
80 fs->regs.reg[5].how = REG_SAVED_OFFSET; | |
81 fs->regs.reg[5].loc.offset = (long)&mctx->gregs[REG_RDI] - new_cfa; | |
82 fs->regs.reg[6].how = REG_SAVED_OFFSET; | |
83 fs->regs.reg[6].loc.offset = (long)&mctx->gregs[REG_RBP] - new_cfa; | |
84 fs->regs.reg[8].how = REG_SAVED_OFFSET; | |
85 fs->regs.reg[8].loc.offset = (long)&mctx->gregs[REG_R8] - new_cfa; | |
86 fs->regs.reg[9].how = REG_SAVED_OFFSET; | |
87 fs->regs.reg[9].loc.offset = (long)&mctx->gregs[REG_R9] - new_cfa; | |
88 fs->regs.reg[10].how = REG_SAVED_OFFSET; | |
89 fs->regs.reg[10].loc.offset = (long)&mctx->gregs[REG_R10] - new_cfa; | |
90 fs->regs.reg[11].how = REG_SAVED_OFFSET; | |
91 fs->regs.reg[11].loc.offset = (long)&mctx->gregs[REG_R11] - new_cfa; | |
92 fs->regs.reg[12].how = REG_SAVED_OFFSET; | |
93 fs->regs.reg[12].loc.offset = (long)&mctx->gregs[REG_R12] - new_cfa; | |
94 fs->regs.reg[13].how = REG_SAVED_OFFSET; | |
95 fs->regs.reg[13].loc.offset = (long)&mctx->gregs[REG_R13] - new_cfa; | |
96 fs->regs.reg[14].how = REG_SAVED_OFFSET; | |
97 fs->regs.reg[14].loc.offset = (long)&mctx->gregs[REG_R14] - new_cfa; | |
98 fs->regs.reg[15].how = REG_SAVED_OFFSET; | |
99 fs->regs.reg[15].loc.offset = (long)&mctx->gregs[REG_R15] - new_cfa; | |
100 fs->regs.reg[16].how = REG_SAVED_OFFSET; | |
101 fs->regs.reg[16].loc.offset = (long)&mctx->gregs[REG_RIP] - new_cfa; | |
102 fs->retaddr_column = 16; | |
103 fs->signal_frame = 1; | |
104 | |
105 return _URC_NO_REASON; | |
106 } | |
107 | |
108 #else | |
109 | |
110 #define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state | |
111 | |
112 static _Unwind_Reason_Code | |
113 x86_fallback_frame_state (struct _Unwind_Context *context, | |
114 _Unwind_FrameState *fs) | |
115 { | |
116 unsigned char *pc = context->ra; | |
117 mcontext_t *mctx; | |
118 long new_cfa; | |
119 | |
120 if (/* Solaris 2.8 - single thread | |
121 ------------------------- | |
122 <sigacthandler+17>: mov 0x10(%ebp),%esi | |
123 <sigacthandler+20>: push %esi | |
124 <sigacthandler+21>: pushl 0xc(%ebp) | |
125 <sigacthandler+24>: mov 0x8(%ebp),%ecx | |
126 <sigacthandler+27>: push %ecx | |
127 <sigacthandler+28>: mov offset(%ebx),%eax | |
128 <sigacthandler+34>: call *(%eax,%ecx,4) | |
129 <sigacthandler+37>: add $0xc,%esp <--- PC | |
130 <sigacthandler+40>: push %esi ... */ | |
131 (*(unsigned long *)(pc - 20) == 0x5610758b | |
132 && *(unsigned long *)(pc - 16) == 0x8b0c75ff | |
133 && *(unsigned long *)(pc - 12) == 0x8b51084d | |
134 && *(unsigned char *)(pc - 8) == 0x83 | |
135 && *(unsigned long *)(pc - 4) == 0x8814ff00 | |
136 && *(unsigned long *)(pc - 0) == 0x560cc483) | |
137 | |
138 || /* Solaris 2.8 - multi thread | |
139 --------------------------- | |
140 <__sighndlr+0>: push %ebp | |
141 <__sighndlr+1>: mov %esp,%ebp | |
142 <__sighndlr+3>: pushl 0x10(%ebp) | |
143 <__sighndlr+6>: pushl 0xc(%ebp) | |
144 <__sighndlr+9>: pushl 0x8(%ebp) | |
145 <__sighndlr+12>: call *0x14(%ebp) | |
146 <__sighndlr+15>: leave <--- PC */ | |
147 (*(unsigned long *)(pc - 15) == 0xffec8b55 | |
148 && *(unsigned long *)(pc - 11) == 0x75ff1075 | |
149 && *(unsigned long *)(pc - 7) == 0x0875ff0c | |
150 && *(unsigned long *)(pc - 3) == 0xc91455ff) | |
151 | |
152 || /* Solaris 2.10 | |
153 ------------ | |
154 <__sighndlr+0>: push %ebp | |
155 <__sighndlr+1>: mov %esp,%ebp | |
156 <__sighndlr+3>: pushl 0x10(%ebp) | |
157 <__sighndlr+6>: pushl 0xc(%ebp) | |
158 <__sighndlr+9>: pushl 0x8(%ebp) | |
159 <__sighndlr+12>: call *0x14(%ebp) | |
160 <__sighndlr+15>: add $0xc,%esp <--- PC | |
161 <__sighndlr+18>: leave | |
162 <__sighndlr+19>: ret */ | |
163 (*(unsigned long *)(pc - 15) == 0xffec8b55 | |
164 && *(unsigned long *)(pc - 11) == 0x75ff1075 | |
165 && *(unsigned long *)(pc - 7) == 0x0875ff0c | |
166 && *(unsigned long *)(pc - 3) == 0x831455ff | |
167 && *(unsigned long *)(pc + 1) == 0xc3c90cc4)) | |
168 { | |
169 struct handler_args { | |
170 int signo; | |
171 siginfo_t *sip; | |
172 ucontext_t *ucontext; | |
173 } *handler_args = context->cfa; | |
174 mctx = &handler_args->ucontext->uc_mcontext; | |
175 } | |
176 else | |
177 return _URC_END_OF_STACK; | |
178 | |
179 new_cfa = mctx->gregs[UESP]; | |
180 | |
181 fs->regs.cfa_how = CFA_REG_OFFSET; | |
182 fs->regs.cfa_reg = 4; | |
183 fs->regs.cfa_offset = new_cfa - (long) context->cfa; | |
184 | |
185 /* The SVR4 register numbering macros aren't usable in libgcc. */ | |
186 fs->regs.reg[0].how = REG_SAVED_OFFSET; | |
187 fs->regs.reg[0].loc.offset = (long)&mctx->gregs[EAX] - new_cfa; | |
188 fs->regs.reg[3].how = REG_SAVED_OFFSET; | |
189 fs->regs.reg[3].loc.offset = (long)&mctx->gregs[EBX] - new_cfa; | |
190 fs->regs.reg[1].how = REG_SAVED_OFFSET; | |
191 fs->regs.reg[1].loc.offset = (long)&mctx->gregs[ECX] - new_cfa; | |
192 fs->regs.reg[2].how = REG_SAVED_OFFSET; | |
193 fs->regs.reg[2].loc.offset = (long)&mctx->gregs[EDX] - new_cfa; | |
194 fs->regs.reg[6].how = REG_SAVED_OFFSET; | |
195 fs->regs.reg[6].loc.offset = (long)&mctx->gregs[ESI] - new_cfa; | |
196 fs->regs.reg[7].how = REG_SAVED_OFFSET; | |
197 fs->regs.reg[7].loc.offset = (long)&mctx->gregs[EDI] - new_cfa; | |
198 fs->regs.reg[5].how = REG_SAVED_OFFSET; | |
199 fs->regs.reg[5].loc.offset = (long)&mctx->gregs[EBP] - new_cfa; | |
200 fs->regs.reg[8].how = REG_SAVED_OFFSET; | |
201 fs->regs.reg[8].loc.offset = (long)&mctx->gregs[EIP] - new_cfa; | |
202 fs->retaddr_column = 8; | |
203 fs->signal_frame = 1; | |
204 | |
205 return _URC_NO_REASON; | |
206 } | |
207 | |
208 #endif |