1 /* DWARF2 EH unwinding support for SPARC Solaris.
2 Copyright (C) 2009 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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.
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/>. */
25 /* Do code reading to identify a signal frame, and set the frame
26 state data appropriately. See unwind-dw2.c for the structs. */
30 #if defined(__arch64__)
32 #define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
34 static _Unwind_Reason_Code
35 sparc64_fallback_frame_state (struct _Unwind_Context *context,
36 _Unwind_FrameState *fs)
38 void *pc = context->ra;
39 void *this_cfa = context->cfa;
40 void *new_cfa, *ra_location, *shifted_ra_location;
43 unsigned char fpu_save;
46 /* This is the observed pattern for the sigacthandler in Solaris 8. */
47 unsigned int sigacthandler_sol8_pattern []
48 = {0x9401400f, 0xca5aafa0, 0x913e2000, 0x892a3003,
49 0xe0590005, 0x9fc40000, 0x9410001a, 0x80a6e008};
51 /* This is the observed pattern for the sigacthandler in Solaris 9. */
52 unsigned int sigacthandler_sol9_pattern []
53 = {0xa33e2000, 0x00000000, 0x892c7003, 0x90100011,
54 0xe0590005, 0x9fc40000, 0x9410001a, 0x80a46008};
56 /* This is the observed pattern for the __sighndlr. */
57 unsigned int sighndlr_pattern []
58 = {0x9de3bf50, 0x90100018, 0x92100019, 0x9fc6c000,
59 0x9410001a, 0x81c7e008, 0x81e80000};
61 /* Deal with frame-less function from which a signal was raised. */
62 if (_Unwind_IsSignalFrame (context))
64 /* The CFA is by definition unmodified in this case. */
65 fs->regs.cfa_how = CFA_REG_OFFSET;
66 fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
67 fs->regs.cfa_offset = 0;
69 /* This is the canonical RA column. */
70 fs->retaddr_column = 15;
72 return _URC_NO_REASON;
75 /* Look for the sigacthandler pattern. The pattern changes slightly
76 in different versions of the operating system, so we skip the
77 comparison against pc-(4*6) for Solaris 9. */
78 if (( *(unsigned int *)(pc-(4*7)) == sigacthandler_sol8_pattern[0]
79 && *(unsigned int *)(pc-(4*6)) == sigacthandler_sol8_pattern[1]
80 && *(unsigned int *)(pc-(4*5)) == sigacthandler_sol8_pattern[2]
81 && *(unsigned int *)(pc-(4*4)) == sigacthandler_sol8_pattern[3]
82 && *(unsigned int *)(pc-(4*3)) == sigacthandler_sol8_pattern[4]
83 && *(unsigned int *)(pc-(4*2)) == sigacthandler_sol8_pattern[5]
84 && *(unsigned int *)(pc-(4*1)) == sigacthandler_sol8_pattern[6]
85 && *(unsigned int *)(pc-(4*0)) == sigacthandler_sol8_pattern[7] ) ||
86 ( *(unsigned int *)(pc-(4*7)) == sigacthandler_sol9_pattern[0]
88 && *(unsigned int *)(pc-(4*5)) == sigacthandler_sol9_pattern[2]
89 && *(unsigned int *)(pc-(4*4)) == sigacthandler_sol9_pattern[3]
90 && *(unsigned int *)(pc-(4*3)) == sigacthandler_sol9_pattern[4]
91 && *(unsigned int *)(pc-(4*2)) == sigacthandler_sol9_pattern[5]
92 && *(unsigned int *)(pc-(4*1)) == sigacthandler_sol9_pattern[6]
93 && *(unsigned int *)(pc-(4*0)) == sigacthandler_sol9_pattern[7] ) )
94 /* We need to move up two frames (the kernel frame and the handler
95 frame). Minimum stack frame size is 176 bytes (128 + 48): 128
96 bytes for spilling register window (16 extended words for in
97 and local registers), and 6 extended words to store at least
98 6 arguments to callees, The kernel frame and the sigacthandler
99 both have this minimal stack. The ucontext_t structure is after
101 regs_off = 176 + 176;
103 /* Look for the __sighndlr pattern. */
104 else if ( *(unsigned int *)(pc-(4*5)) == sighndlr_pattern[0]
105 && *(unsigned int *)(pc-(4*4)) == sighndlr_pattern[1]
106 && *(unsigned int *)(pc-(4*3)) == sighndlr_pattern[2]
107 && *(unsigned int *)(pc-(4*2)) == sighndlr_pattern[3]
108 && *(unsigned int *)(pc-(4*1)) == sighndlr_pattern[4]
109 && *(unsigned int *)(pc-(4*0)) == sighndlr_pattern[5]
110 && *(unsigned int *)(pc+(4*1)) == sighndlr_pattern[6] )
112 /* We have observed different calling frames among different
113 versions of the operating system, so that we need to
114 discriminate using the upper frame. We look for the return
115 address of the caller frame (there is an offset of 15 double
116 words between the frame address and the place where this return
117 address is stored) in order to do some more pattern matching. */
118 unsigned int cuh_pattern
119 = *(unsigned int *)(*(unsigned long *)(this_cfa + 15*8) - 4);
121 if (cuh_pattern == 0x9410001a || cuh_pattern == 0x94100013)
122 /* This matches the call_user_handler pattern for Solaris 9 and
123 for Solaris 8 running inside Solaris Containers respectively.
124 We need to move up four frames (the kernel frame, the signal
125 frame, the call_user_handler frame, the __sighndlr frame).
126 Three of them have the minimum stack frame size (kernel,
127 signal, and __sighndlr frames) of 176 bytes, and there is
128 another with a stack frame of 304 bytes (the call_user_handler
129 frame). The ucontext_t structure is after this offset. */
130 regs_off = 176 + 176 + 176 + 304;
132 /* We need to move up three frames (the kernel frame, the
133 sigacthandler frame, and the __sighndlr frame). The kernel
134 frame has a stack frame size of 176, the __sighndlr frames of
135 304 bytes, and there is a stack frame of 176 bytes for the
136 sigacthandler frame. The ucontext_t structure is after this
138 regs_off = 176 + 304 + 176;
141 /* Exit if the pattern at the return address does not match the
142 previous three patterns. */
144 return _URC_END_OF_STACK;
146 /* FPU information can be extracted from the ucontext_t structure
147 that is the third argument for the signal handler, that is saved
148 in the stack. There are 64 bytes between the beginning of the
149 ucontext_t argument of the signal handler and the uc_mcontext
150 field. There are 176 bytes between the beginning of uc_mcontext
151 and the beginning of the fpregs field. */
152 fpu_save_off = regs_off + (8*10) + 176;
154 /* The fpregs field contains 32 extended words at the beginning that
155 contain the fpu state. Then there are 2 extended words and two
157 fpu_save = *(unsigned char *)(this_cfa + fpu_save_off + (8*32) + (2*8) + 2);
159 /* We need to get the frame pointer for the kernel frame that
160 executes when the signal is raised. This frame is just the
161 following to the application code that generated the signal, so
162 that the later's stack pointer is the former's frame pointer.
163 The stack pointer for the interrupted application code can be
164 calculated from the ucontext_t structure (third argument for the
165 signal handler) that is saved in the stack. There are 10 words
166 between the beginning of the ucontext_t argument of the signal
167 handler and the uc_mcontext.gregs field that contains the
168 registers saved by the signal handler. */
169 new_cfa = *(void **)(this_cfa + regs_off + (8*10) + (REG_SP*8));
170 /* The frame address is %sp + STACK_BIAS in 64-bit mode. */
172 fs->regs.cfa_how = CFA_REG_OFFSET;
173 fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
174 fs->regs.cfa_offset = new_cfa - this_cfa;
176 /* Restore global and out registers (in this order) from the
177 ucontext_t structure, uc_mcontext.gregs field. */
178 for (i = 1; i < 16; i++)
180 /* We never restore %sp as everything is purely CFA-based. */
181 if ((unsigned int) i == __builtin_dwarf_sp_column ())
184 /* First the global registers and then the out registers. */
185 fs->regs.reg[i].how = REG_SAVED_OFFSET;
186 fs->regs.reg[i].loc.offset
187 = this_cfa + regs_off + (8*10) + ((REG_Y+i)*8) - new_cfa;
190 /* Just above the stack pointer there are 16 extended words in which
191 the register window (in and local registers) was saved. */
192 for (i = 0; i < 16; i++)
194 fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
195 fs->regs.reg[i + 16].loc.offset = i*8;
198 /* Check whether we need to restore fpu registers. */
201 for (i = 0; i < 64; i++)
203 if (i > 32 && (i & 1))
206 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
207 fs->regs.reg[i + 32].loc.offset
208 = this_cfa + fpu_save_off + (i*4) - new_cfa;
212 /* State the rules to find the kernel's code "return address", which is
213 the address of the active instruction when the signal was caught.
214 On the SPARC, since RETURN_ADDR_OFFSET (essentially 8) is defined, we
215 need to preventively subtract it from the purported return address. */
216 ra_location = this_cfa + regs_off + (8*10) + (REG_PC*8);
217 shifted_ra_location = this_cfa + regs_off + (8*10) + (REG_Y*8);
218 *(void **)shifted_ra_location = *(void **)ra_location - 8;
219 fs->retaddr_column = 0;
220 fs->regs.reg[0].how = REG_SAVED_OFFSET;
221 fs->regs.reg[0].loc.offset = shifted_ra_location - new_cfa;
222 fs->signal_frame = 1;
224 return _URC_NO_REASON;
227 #define MD_FROB_UPDATE_CONTEXT sparc64_frob_update_context
230 sparc64_frob_update_context (struct _Unwind_Context *context,
231 _Unwind_FrameState *fs)
233 /* The column of %sp contains the old CFA, not the old value of %sp.
234 The CFA offset already comprises the stack bias so, when %sp is the
235 CFA register, we must avoid counting the stack bias twice. Do not
236 do that for signal frames as the offset is artificial for them. */
237 if (fs->regs.cfa_reg == __builtin_dwarf_sp_column ()
238 && fs->regs.cfa_how == CFA_REG_OFFSET
239 && fs->regs.cfa_offset != 0
240 && !fs->signal_frame)
241 context->cfa -= 2047;
246 #define MD_FALLBACK_FRAME_STATE_FOR sparc_fallback_frame_state
248 static _Unwind_Reason_Code
249 sparc_fallback_frame_state (struct _Unwind_Context *context,
250 _Unwind_FrameState *fs)
252 void *pc = context->ra;
253 void *this_cfa = context->cfa;
254 void *new_cfa, *ra_location, *shifted_ra_location;
257 unsigned char fpu_save;
260 /* This is the observed pattern for the sigacthandler. */
261 unsigned int sigacthandler_pattern []
262 = {0x9602400f, 0x92100019, 0x00000000, 0x912e2002,
263 0xe002000a, 0x90100018, 0x9fc40000, 0x9410001a,
266 /* This is the observed pattern for the __libthread_segvhdlr. */
267 unsigned int segvhdlr_pattern []
268 = {0x94102000, 0xe007bfe4, 0x9010001c, 0x92100019,
269 0x9fc40000, 0x9410001a, 0x81c7e008, 0x81e80000,
272 /* This is the observed pattern for the __sighndlr. */
273 unsigned int sighndlr_pattern []
274 = {0x9de3bfa0, 0x90100018, 0x92100019, 0x9fc6c000,
275 0x9410001a, 0x81c7e008, 0x81e80000};
277 /* Deal with frame-less function from which a signal was raised. */
278 if (_Unwind_IsSignalFrame (context))
280 /* The CFA is by definition unmodified in this case. */
281 fs->regs.cfa_how = CFA_REG_OFFSET;
282 fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
283 fs->regs.cfa_offset = 0;
285 /* This is the canonical RA column. */
286 fs->retaddr_column = 15;
288 return _URC_NO_REASON;
291 /* Look for the sigacthandler pattern. The pattern changes slightly
292 in different versions of the operating system, so we skip the
293 comparison against pc-(4*6). */
294 if ( *(unsigned int *)(pc-(4*8)) == sigacthandler_pattern[0]
295 && *(unsigned int *)(pc-(4*7)) == sigacthandler_pattern[1]
297 && *(unsigned int *)(pc-(4*5)) == sigacthandler_pattern[3]
298 && *(unsigned int *)(pc-(4*4)) == sigacthandler_pattern[4]
299 && *(unsigned int *)(pc-(4*3)) == sigacthandler_pattern[5]
300 && *(unsigned int *)(pc-(4*2)) == sigacthandler_pattern[6]
301 && *(unsigned int *)(pc-(4*1)) == sigacthandler_pattern[7]
302 && *(unsigned int *)(pc-(4*0)) == sigacthandler_pattern[8] )
303 /* We need to move up two frames (the kernel frame and the handler
304 frame). Minimum stack frame size is 96 bytes (64 + 4 + 24): 64
305 bytes for spilling register window (16 words for in and local
306 registers), 4 bytes for a pointer to space for callees
307 returning structs, and 24 bytes to store at least six argument
308 to callees. The ucontext_t structure is after this offset. */
311 /* Look for the __libthread_segvhdlr pattern. */
312 else if ( *(unsigned int *)(pc-(4*6)) == segvhdlr_pattern[0]
313 && *(unsigned int *)(pc-(4*5)) == segvhdlr_pattern[1]
314 && *(unsigned int *)(pc-(4*4)) == segvhdlr_pattern[2]
315 && *(unsigned int *)(pc-(4*3)) == segvhdlr_pattern[3]
316 && *(unsigned int *)(pc-(4*2)) == segvhdlr_pattern[4]
317 && *(unsigned int *)(pc-(4*1)) == segvhdlr_pattern[5]
318 && *(unsigned int *)(pc-(4*0)) == segvhdlr_pattern[6]
319 && *(unsigned int *)(pc+(4*1)) == segvhdlr_pattern[7]
320 && *(unsigned int *)(pc+(4*2)) == segvhdlr_pattern[8] )
321 /* We need to move up four frames (the kernel frame, the
322 sigacthandler frame, the __sighndlr frame, and the
323 __libthread_segvhdlr). Two of them have the minimum
324 stack frame size (kernel and __sighndlr frames) of 96 bytes,
325 other has a stack frame of 216 bytes (the sigacthandler frame),
326 and there is another with a stack frame of 128 bytes (the
327 __libthread_segvhdlr). The ucontext_t structure is after this
329 regs_off = 96 + 96 + 128 + 216;
331 /* Look for the __sighndlr pattern. */
332 else if ( *(unsigned int *)(pc-(4*5)) == sighndlr_pattern[0]
333 && *(unsigned int *)(pc-(4*4)) == sighndlr_pattern[1]
334 && *(unsigned int *)(pc-(4*3)) == sighndlr_pattern[2]
335 && *(unsigned int *)(pc-(4*2)) == sighndlr_pattern[3]
336 && *(unsigned int *)(pc-(4*1)) == sighndlr_pattern[4]
337 && *(unsigned int *)(pc-(4*0)) == sighndlr_pattern[5]
338 && *(unsigned int *)(pc+(4*1)) == sighndlr_pattern[6] )
340 /* We have observed different calling frames among different
341 versions of the operating system, so that we need to
342 discriminate using the upper frame. We look for the return
343 address of the caller frame (there is an offset of 15 words
344 between the frame address and the place where this return
345 address is stored) in order to do some more pattern matching. */
346 unsigned int cuh_pattern
347 = *(unsigned int *)(*(unsigned int *)(this_cfa + 15*4) - 4);
349 if (cuh_pattern == 0xd407a04c)
350 /* This matches the call_user_handler pattern for Solaris 10.
351 We need to move up three frames (the kernel frame, the
352 call_user_handler frame, the __sighndlr frame). Two of them
353 have the minimum stack frame size (kernel and __sighndlr
354 frames) of 96 bytes, and there is another with a stack frame
355 of 160 bytes (the call_user_handler frame). The ucontext_t
356 structure is after this offset. */
357 regs_off = 96 + 96 + 160;
358 else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x9410001b)
359 /* This matches the call_user_handler pattern for Solaris 9 and
360 for Solaris 8 running inside Solaris Containers respectively.
361 We need to move up four frames (the kernel frame, the signal
362 frame, the call_user_handler frame, the __sighndlr frame).
363 Three of them have the minimum stack frame size (kernel,
364 signal, and __sighndlr frames) of 96 bytes, and there is
365 another with a stack frame of 160 bytes (the call_user_handler
366 frame). The ucontext_t structure is after this offset. */
367 regs_off = 96 + 96 + 96 + 160;
369 /* We need to move up three frames (the kernel frame, the
370 sigacthandler frame, and the __sighndlr frame). Two of them
371 have the minimum stack frame size (kernel and __sighndlr
372 frames) of 96 bytes, and there is another with a stack frame
373 of 216 bytes (the sigacthandler frame). The ucontext_t
374 structure is after this offset. */
375 regs_off = 96 + 96 + 216;
378 /* Exit if the pattern at the return address does not match the
379 previous three patterns. */
381 return _URC_END_OF_STACK;
383 /* FPU information can be extracted from the ucontext_t structure
384 that is the third argument for the signal handler, that is saved
385 in the stack. There are 10 words between the beginning of the
386 ucontext_t argument of the signal handler and the uc_mcontext
387 field. There are 80 bytes between the beginning of uc_mcontext
388 and the beginning of the fpregs field. */
389 fpu_save_off = regs_off + (4*10) + (4*20);
391 /* The fpregs field contains 32 words at the beginning that contain
392 the fpu state. Then there are 2 words and two bytes. */
393 fpu_save = *(unsigned char *)(this_cfa + fpu_save_off + (4*32) + (2*4) + 2);
395 /* We need to get the frame pointer for the kernel frame that
396 executes when the signal is raised. This frame is just the
397 following to the application code that generated the signal, so
398 that the later's stack pointer is the former's frame pointer.
399 The stack pointer for the interrupted application code can be
400 calculated from the ucontext_t structure (third argument for the
401 signal handler) that is saved in the stack. There are 10 words
402 between the beginning of the ucontext_t argument of the signal
403 handler and the uc_mcontext.gregs field that contains the
404 registers saved by the signal handler. */
405 new_cfa = *(void **)(this_cfa + regs_off + (4*10) + (REG_SP*4));
406 fs->regs.cfa_how = CFA_REG_OFFSET;
407 fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
408 fs->regs.cfa_offset = new_cfa - this_cfa;
410 /* Restore global and out registers (in this order) from the
411 ucontext_t structure, uc_mcontext.gregs field. */
412 for (i = 1; i < 16; i++)
414 /* We never restore %sp as everything is purely CFA-based. */
415 if ((unsigned int) i == __builtin_dwarf_sp_column ())
418 /* First the global registers and then the out registers */
419 fs->regs.reg[i].how = REG_SAVED_OFFSET;
420 fs->regs.reg[i].loc.offset
421 = this_cfa + regs_off + (4*10) + ((REG_Y+i)*4) - new_cfa;
424 /* Just above the stack pointer there are 16 words in which the
425 register window (in and local registers) was saved. */
426 for (i = 0; i < 16; i++)
428 fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
429 fs->regs.reg[i + 16].loc.offset = i*4;
432 /* Check whether we need to restore fpu registers. */
435 for (i = 0; i < 32; i++)
437 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
438 fs->regs.reg[i + 32].loc.offset
439 = this_cfa + fpu_save_off + (i*4) - new_cfa;
443 /* State the rules to find the kernel's code "return address", which is
444 the address of the active instruction when the signal was caught.
445 On the SPARC, since RETURN_ADDR_OFFSET (essentially 8) is defined, we
446 need to preventively subtract it from the purported return address. */
447 ra_location = this_cfa + regs_off + (4*10) + (REG_PC*4);
448 shifted_ra_location = this_cfa + regs_off + (4*10) + (REG_Y*4);
449 *(void **)shifted_ra_location = *(void **)ra_location - 8;
450 fs->retaddr_column = 0;
451 fs->regs.reg[0].how = REG_SAVED_OFFSET;
452 fs->regs.reg[0].loc.offset = shifted_ra_location - new_cfa;
453 fs->signal_frame = 1;
455 return _URC_NO_REASON;