Home | History | Annotate | Download | only in ppc64
      1 /* libunwind - a platform-independent unwind library
      2    Copyright (C) 2006-2007 IBM
      3    Contributed by
      4      Corey Ashford <cjashfor (at) us.ibm.com>
      5      Jose Flavio Aguilar Paulino <jflavio (at) br.ibm.com> <joseflavio (at) gmail.com>
      6 
      7 This file is part of libunwind.
      8 
      9 Permission is hereby granted, free of charge, to any person obtaining
     10 a copy of this software and associated documentation files (the
     11 "Software"), to deal in the Software without restriction, including
     12 without limitation the rights to use, copy, modify, merge, publish,
     13 distribute, sublicense, and/or sell copies of the Software, and to
     14 permit persons to whom the Software is furnished to do so, subject to
     15 the following conditions:
     16 
     17 The above copyright notice and this permission notice shall be
     18 included in all copies or substantial portions of the Software.
     19 
     20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     26 WITH 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 
     44 typedef struct
     45 {
     46   long unsigned back_chain;
     47   long unsigned cr_save;
     48   long unsigned lr_save;
     49   /* many more fields here, but they are unused by this code */
     50 } stack_frame_t;
     51 
     52 
     53 PROTECTED int
     54 unw_step (unw_cursor_t * cursor)
     55 {
     56   struct cursor *c = (struct cursor *) cursor;
     57   stack_frame_t dummy;
     58   unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr;
     59   struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc;
     60   int ret;
     61 
     62   Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip);
     63 
     64   if (c->dwarf.ip == 0)
     65     {
     66       /* Unless the cursor or stack is corrupt or uninitialized,
     67          we've most likely hit the top of the stack */
     68       return 0;
     69     }
     70 
     71   /* Try DWARF-based unwinding... */
     72 
     73   ret = dwarf_step (&c->dwarf);
     74 
     75   if (ret < 0 && ret != -UNW_ENOINFO)
     76     {
     77       Debug (2, "returning %d\n", ret);
     78       return ret;
     79     }
     80 
     81   if (unlikely (ret < 0))
     82     {
     83       if (likely (!unw_is_signal_frame (cursor)))
     84 	{
     85 	  /* DWARF unwinding failed.  As of 09/26/2006, gcc in 64-bit mode
     86 	     produces the mandatory level of traceback record in the code, but
     87 	     I get the impression that this is transitory, that eventually gcc
     88 	     will not produce any traceback records at all.  So, for now, we
     89 	     won't bother to try to find and use these records.
     90 
     91 	     We can, however, attempt to unwind the frame by using the callback
     92 	     chain.  This is very crude, however, and won't be able to unwind
     93 	     any registers besides the IP, SP, and LR . */
     94 
     95 	  back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy);
     96 	  lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy);
     97 
     98 	  back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0);
     99 
    100 	  if ((ret =
    101 	       dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0)
    102 	    {
    103 	      Debug (2,
    104 		 "Unable to retrieve CFA from back chain in stack frame - %d\n",
    105 		 ret);
    106 	      return ret;
    107 	    }
    108 	  if (c->dwarf.cfa == 0)
    109 	    /* Unless the cursor or stack is corrupt or uninitialized we've most
    110 	       likely hit the top of the stack */
    111 	    return 0;
    112 
    113 	  lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0);
    114 
    115 	  if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0)
    116 	    {
    117 	      Debug (2,
    118 		 "Unable to retrieve IP from lr save in stack frame - %d\n",
    119 		 ret);
    120 	      return ret;
    121 	    }
    122 	  ret = 1;
    123 	}
    124       else
    125 	{
    126           /* Find the sigcontext record by taking the CFA and adjusting by
    127              the dummy signal frame size.
    128 
    129              Note that there isn't any way to determined if SA_SIGINFO was
    130              set in the sa_flags parameter to sigaction when the signal
    131              handler was established.  If it was not set, the ucontext
    132              record is not required to be on the stack, in which case the
    133              following code will likely cause a seg fault or other crash
    134              condition.  */
    135 
    136 	  unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE;
    137 
    138 	  Debug (1, "signal frame, skip over trampoline\n");
    139 
    140 	  c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME;
    141 	  c->sigcontext_addr = ucontext;
    142 
    143 	  sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
    144 	  ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0);
    145 
    146 	  ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa);
    147 	  if (ret < 0)
    148 	    {
    149 	      Debug (2, "returning %d\n", ret);
    150 	      return ret;
    151 	    }
    152 	  ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip);
    153 	  if (ret < 0)
    154 	    {
    155 	      Debug (2, "returning %d\n", ret);
    156 	      return ret;
    157 	    }
    158 
    159 	  /* Instead of just restoring the non-volatile registers, do all
    160 	     of the registers for now.  This will incur a performance hit,
    161 	     but it's rare enough not to cause too much of a problem, and
    162 	     might be useful in some cases.  */
    163 	  c->dwarf.loc[UNW_PPC64_R0] =
    164 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0);
    165 	  c->dwarf.loc[UNW_PPC64_R1] =
    166 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
    167 	  c->dwarf.loc[UNW_PPC64_R2] =
    168 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0);
    169 	  c->dwarf.loc[UNW_PPC64_R3] =
    170 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0);
    171 	  c->dwarf.loc[UNW_PPC64_R4] =
    172 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0);
    173 	  c->dwarf.loc[UNW_PPC64_R5] =
    174 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0);
    175 	  c->dwarf.loc[UNW_PPC64_R6] =
    176 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0);
    177 	  c->dwarf.loc[UNW_PPC64_R7] =
    178 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0);
    179 	  c->dwarf.loc[UNW_PPC64_R8] =
    180 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
    181 	  c->dwarf.loc[UNW_PPC64_R9] =
    182 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
    183 	  c->dwarf.loc[UNW_PPC64_R10] =
    184 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
    185 	  c->dwarf.loc[UNW_PPC64_R11] =
    186 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
    187 	  c->dwarf.loc[UNW_PPC64_R12] =
    188 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
    189 	  c->dwarf.loc[UNW_PPC64_R13] =
    190 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
    191 	  c->dwarf.loc[UNW_PPC64_R14] =
    192 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
    193 	  c->dwarf.loc[UNW_PPC64_R15] =
    194 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
    195 	  c->dwarf.loc[UNW_PPC64_R16] =
    196 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0);
    197 	  c->dwarf.loc[UNW_PPC64_R17] =
    198 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0);
    199 	  c->dwarf.loc[UNW_PPC64_R18] =
    200 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0);
    201 	  c->dwarf.loc[UNW_PPC64_R19] =
    202 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0);
    203 	  c->dwarf.loc[UNW_PPC64_R20] =
    204 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0);
    205 	  c->dwarf.loc[UNW_PPC64_R21] =
    206 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0);
    207 	  c->dwarf.loc[UNW_PPC64_R22] =
    208 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0);
    209 	  c->dwarf.loc[UNW_PPC64_R23] =
    210 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0);
    211 	  c->dwarf.loc[UNW_PPC64_R24] =
    212 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0);
    213 	  c->dwarf.loc[UNW_PPC64_R25] =
    214 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0);
    215 	  c->dwarf.loc[UNW_PPC64_R26] =
    216 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0);
    217 	  c->dwarf.loc[UNW_PPC64_R27] =
    218 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0);
    219 	  c->dwarf.loc[UNW_PPC64_R28] =
    220 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0);
    221 	  c->dwarf.loc[UNW_PPC64_R29] =
    222 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0);
    223 	  c->dwarf.loc[UNW_PPC64_R30] =
    224 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0);
    225 	  c->dwarf.loc[UNW_PPC64_R31] =
    226 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0);
    227 
    228 	  c->dwarf.loc[UNW_PPC64_LR] =
    229 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
    230 	  c->dwarf.loc[UNW_PPC64_CTR] =
    231 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0);
    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_PPC64_CR0] =
    236 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0);
    237 	  c->dwarf.loc[UNW_PPC64_XER] =
    238 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0);
    239 	  c->dwarf.loc[UNW_PPC64_NIP] =
    240 	    DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0);
    241 
    242 	  /* TODO: Is there a way of obtaining the value of the
    243 	     pseudo frame pointer (which is sp + some fixed offset, I
    244 	     assume), based on the contents of the ucontext record
    245 	     structure?  For now, set this loc to null. */
    246 	  c->dwarf.loc[UNW_PPC64_FRAME_POINTER] = DWARF_NULL_LOC;
    247 
    248 	  c->dwarf.loc[UNW_PPC64_F0] =
    249 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0);
    250 	  c->dwarf.loc[UNW_PPC64_F1] =
    251 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0);
    252 	  c->dwarf.loc[UNW_PPC64_F2] =
    253 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0);
    254 	  c->dwarf.loc[UNW_PPC64_F3] =
    255 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0);
    256 	  c->dwarf.loc[UNW_PPC64_F4] =
    257 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0);
    258 	  c->dwarf.loc[UNW_PPC64_F5] =
    259 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0);
    260 	  c->dwarf.loc[UNW_PPC64_F6] =
    261 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0);
    262 	  c->dwarf.loc[UNW_PPC64_F7] =
    263 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0);
    264 	  c->dwarf.loc[UNW_PPC64_F8] =
    265 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0);
    266 	  c->dwarf.loc[UNW_PPC64_F9] =
    267 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0);
    268 	  c->dwarf.loc[UNW_PPC64_F10] =
    269 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0);
    270 	  c->dwarf.loc[UNW_PPC64_F11] =
    271 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0);
    272 	  c->dwarf.loc[UNW_PPC64_F12] =
    273 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0);
    274 	  c->dwarf.loc[UNW_PPC64_F13] =
    275 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0);
    276 	  c->dwarf.loc[UNW_PPC64_F14] =
    277 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0);
    278 	  c->dwarf.loc[UNW_PPC64_F15] =
    279 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0);
    280 	  c->dwarf.loc[UNW_PPC64_F16] =
    281 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0);
    282 	  c->dwarf.loc[UNW_PPC64_F17] =
    283 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0);
    284 	  c->dwarf.loc[UNW_PPC64_F18] =
    285 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0);
    286 	  c->dwarf.loc[UNW_PPC64_F19] =
    287 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0);
    288 	  c->dwarf.loc[UNW_PPC64_F20] =
    289 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0);
    290 	  c->dwarf.loc[UNW_PPC64_F21] =
    291 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0);
    292 	  c->dwarf.loc[UNW_PPC64_F22] =
    293 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0);
    294 	  c->dwarf.loc[UNW_PPC64_F23] =
    295 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0);
    296 	  c->dwarf.loc[UNW_PPC64_F24] =
    297 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0);
    298 	  c->dwarf.loc[UNW_PPC64_F25] =
    299 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0);
    300 	  c->dwarf.loc[UNW_PPC64_F26] =
    301 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0);
    302 	  c->dwarf.loc[UNW_PPC64_F27] =
    303 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0);
    304 	  c->dwarf.loc[UNW_PPC64_F28] =
    305 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0);
    306 	  c->dwarf.loc[UNW_PPC64_F29] =
    307 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0);
    308 	  c->dwarf.loc[UNW_PPC64_F30] =
    309 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0);
    310 	  c->dwarf.loc[UNW_PPC64_F31] =
    311 	    DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0);
    312 	  /* Note that there is no .eh_section register column for the
    313 	     FPSCR register.  I don't know why this is.  */
    314 
    315 	  v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0);
    316 	  ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr);
    317 	  if (ret < 0)
    318 	    {
    319 	      Debug (2, "returning %d\n", ret);
    320 	      return ret;
    321 	    }
    322 	  if (v_regs_ptr != 0)
    323 	    {
    324 	      /* The v_regs_ptr is not null.  Set all of the AltiVec locs */
    325 
    326 	      c->dwarf.loc[UNW_PPC64_V0] =
    327 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0);
    328 	      c->dwarf.loc[UNW_PPC64_V1] =
    329 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0);
    330 	      c->dwarf.loc[UNW_PPC64_V2] =
    331 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0);
    332 	      c->dwarf.loc[UNW_PPC64_V3] =
    333 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0);
    334 	      c->dwarf.loc[UNW_PPC64_V4] =
    335 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0);
    336 	      c->dwarf.loc[UNW_PPC64_V5] =
    337 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0);
    338 	      c->dwarf.loc[UNW_PPC64_V6] =
    339 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0);
    340 	      c->dwarf.loc[UNW_PPC64_V7] =
    341 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0);
    342 	      c->dwarf.loc[UNW_PPC64_V8] =
    343 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0);
    344 	      c->dwarf.loc[UNW_PPC64_V9] =
    345 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0);
    346 	      c->dwarf.loc[UNW_PPC64_V10] =
    347 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0);
    348 	      c->dwarf.loc[UNW_PPC64_V11] =
    349 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0);
    350 	      c->dwarf.loc[UNW_PPC64_V12] =
    351 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0);
    352 	      c->dwarf.loc[UNW_PPC64_V13] =
    353 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0);
    354 	      c->dwarf.loc[UNW_PPC64_V14] =
    355 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0);
    356 	      c->dwarf.loc[UNW_PPC64_V15] =
    357 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0);
    358 	      c->dwarf.loc[UNW_PPC64_V16] =
    359 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0);
    360 	      c->dwarf.loc[UNW_PPC64_V17] =
    361 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0);
    362 	      c->dwarf.loc[UNW_PPC64_V18] =
    363 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0);
    364 	      c->dwarf.loc[UNW_PPC64_V19] =
    365 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0);
    366 	      c->dwarf.loc[UNW_PPC64_V20] =
    367 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0);
    368 	      c->dwarf.loc[UNW_PPC64_V21] =
    369 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0);
    370 	      c->dwarf.loc[UNW_PPC64_V22] =
    371 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0);
    372 	      c->dwarf.loc[UNW_PPC64_V23] =
    373 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0);
    374 	      c->dwarf.loc[UNW_PPC64_V24] =
    375 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0);
    376 	      c->dwarf.loc[UNW_PPC64_V25] =
    377 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0);
    378 	      c->dwarf.loc[UNW_PPC64_V26] =
    379 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0);
    380 	      c->dwarf.loc[UNW_PPC64_V27] =
    381 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0);
    382 	      c->dwarf.loc[UNW_PPC64_V28] =
    383 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0);
    384 	      c->dwarf.loc[UNW_PPC64_V29] =
    385 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0);
    386 	      c->dwarf.loc[UNW_PPC64_V30] =
    387 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0);
    388 	      c->dwarf.loc[UNW_PPC64_V31] =
    389 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0);
    390 	      c->dwarf.loc[UNW_PPC64_VRSAVE] =
    391 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0);
    392 	      c->dwarf.loc[UNW_PPC64_VSCR] =
    393 		DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0);
    394 	    }
    395 	  else
    396 	    {
    397 	      c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC;
    398 	      c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC;
    399 	      c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC;
    400 	      c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC;
    401 	      c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC;
    402 	      c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC;
    403 	      c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC;
    404 	      c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC;
    405 	      c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC;
    406 	      c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC;
    407 	      c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC;
    408 	      c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC;
    409 	      c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC;
    410 	      c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC;
    411 	      c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC;
    412 	      c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC;
    413 	      c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC;
    414 	      c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC;
    415 	      c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC;
    416 	      c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC;
    417 	      c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC;
    418 	      c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC;
    419 	      c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC;
    420 	      c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC;
    421 	      c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC;
    422 	      c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC;
    423 	      c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC;
    424 	      c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC;
    425 	      c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC;
    426 	      c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC;
    427 	      c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC;
    428 	      c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC;
    429 	      c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC;
    430 	      c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC;
    431 	    }
    432 	  ret = 1;
    433 	}
    434     }
    435   return ret;
    436 }
    437