1/* libunwind - a platform-independent unwind library 2 Copyright (C) 2006-2007 IBM 3 Contributed by 4 Corey Ashford <cjashfor@us.ibm.com> 5 Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com> 6 7This file is part of libunwind. 8 9Permission is hereby granted, free of charge, to any person obtaining 10a copy of this software and associated documentation files (the 11"Software"), to deal in the Software without restriction, including 12without limitation the rights to use, copy, modify, merge, publish, 13distribute, sublicense, and/or sell copies of the Software, and to 14permit persons to whom the Software is furnished to do so, subject to 15the following conditions: 16 17The above copyright notice and this permission notice shall be 18included in all copies or substantial portions of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 27 28#include "unwind_i.h" 29#include "ucontext_i.h" 30#include <signal.h> 31 32/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is 33 defined there only when __KERNEL__ is defined. We reproduce it here for 34 our use at the user level in order to locate the ucontext record, which 35 appears to be at this offset relative to the stack pointer when in the 36 context of the signal handler return trampoline code - 37 __kernel_sigtramp_rt64. */ 38#define __SIGNAL_FRAMESIZE 128 39 40/* This definition comes from the document "64-bit PowerPC ELF Application 41 Binary Interface Supplement 1.9", section 3.2.2. 42 http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ 43 44typedef struct 45{ 46 long unsigned back_chain; 47 long unsigned lr_save; 48 /* many more fields here, but they are unused by this code */ 49} stack_frame_t; 50 51 52PROTECTED int 53unw_step (unw_cursor_t * cursor) 54{ 55 struct cursor *c = (struct cursor *) cursor; 56 stack_frame_t dummy; 57 unw_word_t back_chain_offset, lr_save_offset; 58 struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc; 59 int ret; 60 61 Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); 62 63 if (c->dwarf.ip == 0) 64 { 65 /* Unless the cursor or stack is corrupt or uninitialized, 66 we've most likely hit the top of the stack */ 67 return 0; 68 } 69 70 /* Try DWARF-based unwinding... */ 71 72 ret = dwarf_step (&c->dwarf); 73 74 if (ret < 0 && ret != -UNW_ENOINFO) 75 { 76 Debug (2, "returning %d\n", ret); 77 return ret; 78 } 79 80 if (unlikely (ret < 0)) 81 { 82 if (likely (!unw_is_signal_frame (cursor))) 83 { 84 /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode 85 produces the mandatory level of traceback record in the code, but 86 I get the impression that this is transitory, that eventually gcc 87 will not produce any traceback records at all. So, for now, we 88 won't bother to try to find and use these records. 89 90 We can, however, attempt to unwind the frame by using the callback 91 chain. This is very crude, however, and won't be able to unwind 92 any registers besides the IP, SP, and LR . */ 93 94 back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); 95 lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); 96 97 back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); 98 99 if ((ret = 100 dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) 101 { 102 Debug (2, 103 "Unable to retrieve CFA from back chain in stack frame - %d\n", 104 ret); 105 return ret; 106 } 107 if (c->dwarf.cfa == 0) 108 /* Unless the cursor or stack is corrupt or uninitialized we've most 109 likely hit the top of the stack */ 110 return 0; 111 112 lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); 113 114 if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) 115 { 116 Debug (2, 117 "Unable to retrieve IP from lr save in stack frame - %d\n", 118 ret); 119 return ret; 120 } 121 ret = 1; 122 } 123 else 124 { 125 /* Find the sigcontext record by taking the CFA and adjusting by 126 the dummy signal frame size. 127 128 Note that there isn't any way to determined if SA_SIGINFO was 129 set in the sa_flags parameter to sigaction when the signal 130 handler was established. If it was not set, the ucontext 131 record is not required to be on the stack, in which case the 132 following code will likely cause a seg fault or other crash 133 condition. */ 134 135 unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; 136 137 Debug (1, "signal frame, skip over trampoline\n"); 138 139 c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; 140 c->sigcontext_addr = ucontext; 141 142 sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); 143 ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); 144 145 ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); 146 if (ret < 0) 147 { 148 Debug (2, "returning %d\n", ret); 149 return ret; 150 } 151 ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); 152 if (ret < 0) 153 { 154 Debug (2, "returning %d\n", ret); 155 return ret; 156 } 157 158 /* Instead of just restoring the non-volatile registers, do all 159 of the registers for now. This will incur a performance hit, 160 but it's rare enough not to cause too much of a problem, and 161 might be useful in some cases. */ 162 c->dwarf.loc[UNW_PPC32_R0] = 163 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); 164 c->dwarf.loc[UNW_PPC32_R1] = 165 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); 166 c->dwarf.loc[UNW_PPC32_R2] = 167 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); 168 c->dwarf.loc[UNW_PPC32_R3] = 169 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); 170 c->dwarf.loc[UNW_PPC32_R4] = 171 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); 172 c->dwarf.loc[UNW_PPC32_R5] = 173 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); 174 c->dwarf.loc[UNW_PPC32_R6] = 175 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); 176 c->dwarf.loc[UNW_PPC32_R7] = 177 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); 178 c->dwarf.loc[UNW_PPC32_R8] = 179 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); 180 c->dwarf.loc[UNW_PPC32_R9] = 181 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); 182 c->dwarf.loc[UNW_PPC32_R10] = 183 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); 184 c->dwarf.loc[UNW_PPC32_R11] = 185 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); 186 c->dwarf.loc[UNW_PPC32_R12] = 187 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); 188 c->dwarf.loc[UNW_PPC32_R13] = 189 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); 190 c->dwarf.loc[UNW_PPC32_R14] = 191 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); 192 c->dwarf.loc[UNW_PPC32_R15] = 193 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); 194 c->dwarf.loc[UNW_PPC32_R16] = 195 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); 196 c->dwarf.loc[UNW_PPC32_R17] = 197 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); 198 c->dwarf.loc[UNW_PPC32_R18] = 199 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); 200 c->dwarf.loc[UNW_PPC32_R19] = 201 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); 202 c->dwarf.loc[UNW_PPC32_R20] = 203 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); 204 c->dwarf.loc[UNW_PPC32_R21] = 205 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); 206 c->dwarf.loc[UNW_PPC32_R22] = 207 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); 208 c->dwarf.loc[UNW_PPC32_R23] = 209 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); 210 c->dwarf.loc[UNW_PPC32_R24] = 211 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); 212 c->dwarf.loc[UNW_PPC32_R25] = 213 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); 214 c->dwarf.loc[UNW_PPC32_R26] = 215 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); 216 c->dwarf.loc[UNW_PPC32_R27] = 217 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); 218 c->dwarf.loc[UNW_PPC32_R28] = 219 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); 220 c->dwarf.loc[UNW_PPC32_R29] = 221 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); 222 c->dwarf.loc[UNW_PPC32_R30] = 223 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); 224 c->dwarf.loc[UNW_PPC32_R31] = 225 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); 226 227 c->dwarf.loc[UNW_PPC32_LR] = 228 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); 229 c->dwarf.loc[UNW_PPC32_CTR] = 230 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); 231 232 /* This CR0 assignment is probably wrong. There are 8 dwarf columns 233 assigned to the CR registers, but only one CR register in the 234 mcontext structure */ 235 c->dwarf.loc[UNW_PPC32_CCR] = 236 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); 237 c->dwarf.loc[UNW_PPC32_XER] = 238 DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); 239 240 c->dwarf.loc[UNW_PPC32_F0] = 241 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); 242 c->dwarf.loc[UNW_PPC32_F1] = 243 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); 244 c->dwarf.loc[UNW_PPC32_F2] = 245 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); 246 c->dwarf.loc[UNW_PPC32_F3] = 247 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); 248 c->dwarf.loc[UNW_PPC32_F4] = 249 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); 250 c->dwarf.loc[UNW_PPC32_F5] = 251 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); 252 c->dwarf.loc[UNW_PPC32_F6] = 253 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); 254 c->dwarf.loc[UNW_PPC32_F7] = 255 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); 256 c->dwarf.loc[UNW_PPC32_F8] = 257 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); 258 c->dwarf.loc[UNW_PPC32_F9] = 259 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); 260 c->dwarf.loc[UNW_PPC32_F10] = 261 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); 262 c->dwarf.loc[UNW_PPC32_F11] = 263 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); 264 c->dwarf.loc[UNW_PPC32_F12] = 265 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); 266 c->dwarf.loc[UNW_PPC32_F13] = 267 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); 268 c->dwarf.loc[UNW_PPC32_F14] = 269 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); 270 c->dwarf.loc[UNW_PPC32_F15] = 271 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); 272 c->dwarf.loc[UNW_PPC32_F16] = 273 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); 274 c->dwarf.loc[UNW_PPC32_F17] = 275 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); 276 c->dwarf.loc[UNW_PPC32_F18] = 277 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); 278 c->dwarf.loc[UNW_PPC32_F19] = 279 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); 280 c->dwarf.loc[UNW_PPC32_F20] = 281 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); 282 c->dwarf.loc[UNW_PPC32_F21] = 283 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); 284 c->dwarf.loc[UNW_PPC32_F22] = 285 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); 286 c->dwarf.loc[UNW_PPC32_F23] = 287 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); 288 c->dwarf.loc[UNW_PPC32_F24] = 289 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); 290 c->dwarf.loc[UNW_PPC32_F25] = 291 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); 292 c->dwarf.loc[UNW_PPC32_F26] = 293 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); 294 c->dwarf.loc[UNW_PPC32_F27] = 295 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); 296 c->dwarf.loc[UNW_PPC32_F28] = 297 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); 298 c->dwarf.loc[UNW_PPC32_F29] = 299 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); 300 c->dwarf.loc[UNW_PPC32_F30] = 301 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); 302 c->dwarf.loc[UNW_PPC32_F31] = 303 DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); 304 305 ret = 1; 306 } 307 } 308 return ret; 309} 310