Home | History | Annotate | Line # | Download | only in rs6000
darwin-fallback.c revision 1.1.1.11
      1       1.1  mrg /* Fallback frame-state unwinder for Darwin.
      2  1.1.1.11  mrg    Copyright (C) 2004-2024 Free Software Foundation, Inc.
      3       1.1  mrg 
      4       1.1  mrg    This file is part of GCC.
      5       1.1  mrg 
      6       1.1  mrg    GCC is free software; you can redistribute it and/or modify it
      7       1.1  mrg    under the terms of the GNU General Public License as published by
      8       1.1  mrg    the Free Software Foundation; either version 3, or (at your option)
      9       1.1  mrg    any later version.
     10       1.1  mrg 
     11       1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT
     12       1.1  mrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13       1.1  mrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14       1.1  mrg    License for more details.
     15       1.1  mrg 
     16       1.1  mrg    Under Section 7 of GPL version 3, you are granted additional
     17       1.1  mrg    permissions described in the GCC Runtime Library Exception, version
     18       1.1  mrg    3.1, as published by the Free Software Foundation.
     19       1.1  mrg 
     20       1.1  mrg    You should have received a copy of the GNU General Public License and
     21       1.1  mrg    a copy of the GCC Runtime Library Exception along with this program;
     22       1.1  mrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23       1.1  mrg    <http://www.gnu.org/licenses/>.  */
     24       1.1  mrg 
     25       1.1  mrg #ifdef __ppc__
     26       1.1  mrg 
     27       1.1  mrg #include "tconfig.h"
     28       1.1  mrg #include "tsystem.h"
     29       1.1  mrg #include "coretypes.h"
     30       1.1  mrg #include "tm.h"
     31       1.1  mrg #include "libgcc_tm.h"
     32       1.1  mrg #include "dwarf2.h"
     33       1.1  mrg #include "unwind.h"
     34       1.1  mrg #include "unwind-dw2.h"
     35       1.1  mrg #include <stdint.h>
     36       1.1  mrg #include <stdbool.h>
     37       1.1  mrg #include <sys/types.h>
     38       1.1  mrg #include <signal.h>
     39       1.1  mrg 
     40       1.1  mrg #define R_LR		65
     41       1.1  mrg #define R_CTR		66
     42       1.1  mrg #define R_CR2		70
     43       1.1  mrg #define R_XER		76
     44       1.1  mrg #define R_VR0		77
     45       1.1  mrg #define R_VRSAVE	109
     46       1.1  mrg #define R_VSCR		110
     47       1.1  mrg #define R_SPEFSCR	112
     48       1.1  mrg 
     49       1.1  mrg typedef unsigned long reg_unit;
     50       1.1  mrg 
     51       1.1  mrg /* Place in GPRS the parameters to the first 'sc' instruction that would
     52       1.1  mrg    have been executed if we were returning from this CONTEXT, or
     53       1.1  mrg    return false if an unexpected instruction is encountered.  */
     54       1.1  mrg 
     55       1.1  mrg static bool
     56       1.1  mrg interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
     57       1.1  mrg {
     58       1.1  mrg   uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
     59       1.1  mrg   uint32_t cr;
     60       1.1  mrg   reg_unit lr = (reg_unit) pc;
     61       1.1  mrg   reg_unit ctr = 0;
     62       1.1  mrg   uint32_t *invalid_address = NULL;
     63       1.1  mrg 
     64       1.1  mrg   int i;
     65       1.1  mrg 
     66       1.1  mrg   for (i = 0; i < 13; i++)
     67       1.1  mrg     gprs[i] = 1;
     68       1.1  mrg   gprs[1] = _Unwind_GetCFA (context);
     69       1.1  mrg   for (; i < 32; i++)
     70       1.1  mrg     gprs[i] = _Unwind_GetGR (context, i);
     71       1.1  mrg   cr = _Unwind_GetGR (context, R_CR2);
     72       1.1  mrg 
     73       1.1  mrg   /* For each supported Libc, we have to track the code flow
     74       1.1  mrg      all the way back into the kernel.
     75       1.1  mrg 
     76       1.1  mrg      This code is believed to support all released Libc/Libsystem builds since
     77       1.1  mrg      Jaguar 6C115, including all the security updates.  To be precise,
     78       1.1  mrg 
     79       1.1  mrg      Libc	Libsystem	Build(s)
     80       1.1  mrg      262~1	60~37		6C115
     81       1.1  mrg      262~1	60.2~4		6D52
     82       1.1  mrg      262~1	61~3		6F21-6F22
     83       1.1  mrg      262~1	63~24		6G30-6G37
     84       1.1  mrg      262~1	63~32		6I34-6I35
     85       1.1  mrg      262~1	63~64		6L29-6L60
     86       1.1  mrg      262.4.1~1	63~84		6L123-6R172
     87       1.1  mrg 
     88       1.1  mrg      320~1	71~101		7B85-7D28
     89       1.1  mrg      320~1	71~266		7F54-7F56
     90       1.1  mrg      320~1	71~288		7F112
     91       1.1  mrg      320~1	71~289		7F113
     92       1.1  mrg      320.1.3~1	71.1.1~29	7H60-7H105
     93       1.1  mrg      320.1.3~1	71.1.1~30	7H110-7H113
     94       1.1  mrg      320.1.3~1	71.1.1~31	7H114
     95       1.1  mrg 
     96       1.1  mrg      That's a big table!  It would be insane to try to keep track of
     97       1.1  mrg      every little detail, so we just read the code itself and do what
     98       1.1  mrg      it would do.
     99       1.1  mrg   */
    100       1.1  mrg 
    101       1.1  mrg   for (;;)
    102       1.1  mrg     {
    103       1.1  mrg       uint32_t ins = *pc++;
    104       1.1  mrg 
    105       1.1  mrg       if ((ins & 0xFC000003) == 0x48000000)  /* b instruction */
    106       1.1  mrg 	{
    107       1.1  mrg 	  pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
    108       1.1  mrg 	  continue;
    109       1.1  mrg 	}
    110       1.1  mrg       if ((ins & 0xFC600000) == 0x2C000000)  /* cmpwi */
    111       1.1  mrg 	{
    112       1.1  mrg 	  int32_t val1 = (int16_t) ins;
    113       1.1  mrg 	  int32_t val2 = gprs[ins >> 16 & 0x1F];
    114       1.1  mrg 	  /* Only beq and bne instructions are supported, so we only
    115       1.1  mrg 	     need to set the EQ bit.  */
    116       1.1  mrg 	  uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
    117       1.1  mrg 	  if (val1 == val2)
    118       1.1  mrg 	    cr |= mask;
    119       1.1  mrg 	  else
    120       1.1  mrg 	    cr &= ~mask;
    121       1.1  mrg 	  continue;
    122       1.1  mrg 	}
    123       1.1  mrg       if ((ins & 0xFEC38003) == 0x40820000)  /* forwards beq/bne */
    124       1.1  mrg 	{
    125       1.1  mrg 	  if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
    126       1.1  mrg 	    pc += (ins & 0x7FFC) / 4 - 1;
    127       1.1  mrg 	  continue;
    128       1.1  mrg 	}
    129       1.1  mrg       if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
    130       1.1  mrg 	{
    131       1.1  mrg 	  gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
    132       1.1  mrg 				     | gprs [ins >> 21 & 0x1F]);
    133       1.1  mrg 	  continue;
    134       1.1  mrg 	}
    135       1.1  mrg       if (ins >> 26 == 0x0E)  /* addi, including li */
    136       1.1  mrg 	{
    137       1.1  mrg 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
    138       1.1  mrg 	  gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
    139       1.1  mrg 	  continue;
    140       1.1  mrg 	}
    141       1.1  mrg       if (ins >> 26 == 0x0F)  /* addis, including lis */
    142       1.1  mrg 	{
    143       1.1  mrg 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
    144       1.1  mrg 	  gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
    145       1.1  mrg 	  continue;
    146       1.1  mrg 	}
    147       1.1  mrg       if (ins >> 26 == 0x20)  /* lwz */
    148       1.1  mrg 	{
    149       1.1  mrg 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
    150       1.1  mrg 	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
    151       1.1  mrg 	  if (p == invalid_address)
    152       1.1  mrg 	    return false;
    153       1.1  mrg 	  gprs [ins >> 21 & 0x1F] = *p;
    154       1.1  mrg 	  continue;
    155       1.1  mrg 	}
    156       1.1  mrg       if (ins >> 26 == 0x21)  /* lwzu */
    157       1.1  mrg 	{
    158       1.1  mrg 	  uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
    159       1.1  mrg 	  if (p == invalid_address)
    160       1.1  mrg 	    return false;
    161       1.1  mrg 	  gprs [ins >> 21 & 0x1F] = *p;
    162       1.1  mrg 	  continue;
    163       1.1  mrg 	}
    164       1.1  mrg       if (ins >> 26 == 0x24)  /* stw */
    165       1.1  mrg 	/* What we hope this is doing is '--in_sigtramp'.  We don't want
    166       1.1  mrg 	   to actually store to memory, so just make a note of the
    167       1.1  mrg 	   address and refuse to load from it.  */
    168       1.1  mrg 	{
    169       1.1  mrg 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
    170       1.1  mrg 	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
    171       1.1  mrg 	  if (p == NULL || invalid_address != NULL)
    172       1.1  mrg 	    return false;
    173       1.1  mrg 	  invalid_address = p;
    174       1.1  mrg 	  continue;
    175       1.1  mrg 	}
    176       1.1  mrg       if (ins >> 26 == 0x2E) /* lmw */
    177       1.1  mrg 	{
    178       1.1  mrg 	  reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
    179       1.1  mrg 	  uint32_t *p = (uint32_t *)(src + (int16_t) ins);
    180       1.1  mrg 	  int i;
    181       1.1  mrg 
    182       1.1  mrg 	  for (i = (ins >> 21 & 0x1F); i < 32; i++)
    183       1.1  mrg 	    {
    184       1.1  mrg 	      if (p == invalid_address)
    185       1.1  mrg 		return false;
    186       1.1  mrg 	      gprs[i] = *p++;
    187       1.1  mrg 	    }
    188       1.1  mrg 	  continue;
    189       1.1  mrg 	}
    190       1.1  mrg       if ((ins & 0xFC1FFFFF) == 0x7c0803a6)  /* mtlr */
    191       1.1  mrg 	{
    192       1.1  mrg 	  lr = gprs [ins >> 21 & 0x1F];
    193       1.1  mrg 	  continue;
    194       1.1  mrg 	}
    195       1.1  mrg       if ((ins & 0xFC1FFFFF) == 0x7c0802a6)  /* mflr */
    196       1.1  mrg 	{
    197       1.1  mrg 	  gprs [ins >> 21 & 0x1F] = lr;
    198       1.1  mrg 	  continue;
    199       1.1  mrg 	}
    200       1.1  mrg       if ((ins & 0xFC1FFFFF) == 0x7c0903a6)  /* mtctr */
    201       1.1  mrg 	{
    202       1.1  mrg 	  ctr = gprs [ins >> 21 & 0x1F];
    203       1.1  mrg 	  continue;
    204       1.1  mrg 	}
    205       1.1  mrg       /* The PowerPC User's Manual says that bit 11 of the mtcrf
    206       1.1  mrg 	 instruction is reserved and should be set to zero, but it
    207       1.1  mrg 	 looks like the Darwin assembler doesn't do that... */
    208       1.1  mrg       if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
    209       1.1  mrg 	{
    210       1.1  mrg 	  int i;
    211       1.1  mrg 	  uint32_t mask = 0;
    212       1.1  mrg 	  for (i = 0; i < 8; i++)
    213       1.1  mrg 	    mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
    214       1.1  mrg 	  cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
    215       1.1  mrg 	  continue;
    216       1.1  mrg 	}
    217       1.1  mrg       if (ins == 0x429f0005)  /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
    218       1.1  mrg 	{
    219       1.1  mrg 	  lr = (reg_unit) pc;
    220       1.1  mrg 	  continue;
    221       1.1  mrg 	}
    222       1.1  mrg       if (ins == 0x4e800420) /* bctr */
    223       1.1  mrg 	{
    224       1.1  mrg 	  pc = (uint32_t *) ctr;
    225       1.1  mrg 	  continue;
    226       1.1  mrg 	}
    227       1.1  mrg       if (ins == 0x44000002) /* sc */
    228       1.1  mrg 	return true;
    229       1.1  mrg 
    230       1.1  mrg       return false;
    231       1.1  mrg     }
    232       1.1  mrg }
    233       1.1  mrg 
    234       1.1  mrg /* We used to include <ucontext.h> and <mach/thread_status.h>,
    235       1.1  mrg    but they change so much between different Darwin system versions
    236       1.1  mrg    that it's much easier to just write the structures involved here
    237       1.1  mrg    directly.  */
    238       1.1  mrg 
    239       1.1  mrg /* These defines are from the kernel's bsd/dev/ppc/unix_signal.c.  */
    240       1.1  mrg #define UC_TRAD                 1
    241       1.1  mrg #define UC_TRAD_VEC             6
    242       1.1  mrg #define UC_TRAD64               20
    243       1.1  mrg #define UC_TRAD64_VEC           25
    244       1.1  mrg #define UC_FLAVOR               30
    245       1.1  mrg #define UC_FLAVOR_VEC           35
    246       1.1  mrg #define UC_FLAVOR64             40
    247       1.1  mrg #define UC_FLAVOR64_VEC         45
    248       1.1  mrg #define UC_DUAL                 50
    249       1.1  mrg #define UC_DUAL_VEC             55
    250       1.1  mrg 
    251       1.1  mrg struct gcc_ucontext
    252       1.1  mrg {
    253       1.1  mrg   int onstack;
    254       1.1  mrg   sigset_t sigmask;
    255       1.1  mrg   void * stack_sp;
    256       1.1  mrg   size_t stack_sz;
    257       1.1  mrg   int stack_flags;
    258       1.1  mrg   struct gcc_ucontext *link;
    259       1.1  mrg   size_t mcsize;
    260       1.1  mrg   struct gcc_mcontext32 *mcontext;
    261       1.1  mrg };
    262       1.1  mrg 
    263       1.1  mrg struct gcc_float_vector_state
    264       1.1  mrg {
    265       1.1  mrg   double fpregs[32];
    266       1.1  mrg   uint32_t fpscr_pad;
    267       1.1  mrg   uint32_t fpscr;
    268       1.1  mrg   uint32_t save_vr[32][4];
    269       1.1  mrg   uint32_t save_vscr[4];
    270       1.1  mrg };
    271       1.1  mrg 
    272       1.1  mrg struct gcc_mcontext32 {
    273       1.1  mrg   uint32_t dar;
    274       1.1  mrg   uint32_t dsisr;
    275       1.1  mrg   uint32_t exception;
    276       1.1  mrg   uint32_t padding1[5];
    277       1.1  mrg   uint32_t srr0;
    278       1.1  mrg   uint32_t srr1;
    279       1.1  mrg   uint32_t gpr[32];
    280       1.1  mrg   uint32_t cr;
    281       1.1  mrg   uint32_t xer;
    282       1.1  mrg   uint32_t lr;
    283       1.1  mrg   uint32_t ctr;
    284       1.1  mrg   uint32_t mq;
    285       1.1  mrg   uint32_t vrsave;
    286       1.1  mrg   struct gcc_float_vector_state fvs;
    287       1.1  mrg };
    288       1.1  mrg 
    289       1.1  mrg /* These are based on /usr/include/ppc/ucontext.h and
    290       1.1  mrg    /usr/include/mach/ppc/thread_status.h, but rewritten to be more
    291       1.1  mrg    convenient, to compile on Jaguar, and to work around Radar 3712064
    292       1.1  mrg    on Panther, which is that the 'es' field of 'struct mcontext64' has
    293       1.1  mrg    the wrong type (doh!).  */
    294       1.1  mrg 
    295       1.1  mrg struct gcc_mcontext64 {
    296       1.1  mrg   uint64_t dar;
    297       1.1  mrg   uint32_t dsisr;
    298       1.1  mrg   uint32_t exception;
    299       1.1  mrg   uint32_t padding1[4];
    300       1.1  mrg   uint64_t srr0;
    301       1.1  mrg   uint64_t srr1;
    302       1.1  mrg   uint32_t gpr[32][2];
    303       1.1  mrg   uint32_t cr;
    304       1.1  mrg   uint32_t xer[2];  /* These are arrays because the original structure has them misaligned.  */
    305       1.1  mrg   uint32_t lr[2];
    306       1.1  mrg   uint32_t ctr[2];
    307       1.1  mrg   uint32_t vrsave;
    308       1.1  mrg   struct gcc_float_vector_state fvs;
    309       1.1  mrg };
    310       1.1  mrg 
    311       1.1  mrg #define UC_FLAVOR_SIZE \
    312       1.1  mrg   (sizeof (struct gcc_mcontext32) - 33*16)
    313       1.1  mrg 
    314       1.1  mrg #define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32))
    315       1.1  mrg 
    316       1.1  mrg #define UC_FLAVOR64_SIZE \
    317       1.1  mrg   (sizeof (struct gcc_mcontext64) - 33*16)
    318       1.1  mrg 
    319       1.1  mrg #define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
    320       1.1  mrg 
    321       1.1  mrg /* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
    322       1.1  mrg    to represent the execution of a signal return; or, if not a signal
    323       1.1  mrg    return, return false.  */
    324       1.1  mrg 
    325       1.1  mrg static bool
    326       1.1  mrg handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
    327       1.1  mrg 		_Unwind_Ptr old_cfa)
    328       1.1  mrg {
    329       1.1  mrg   struct gcc_ucontext *uctx;
    330       1.1  mrg   bool is_64, is_vector;
    331       1.1  mrg   struct gcc_float_vector_state * float_vector_state;
    332       1.1  mrg   _Unwind_Ptr new_cfa;
    333       1.1  mrg   int i;
    334       1.1  mrg   static _Unwind_Ptr return_addr;
    335       1.1  mrg 
    336       1.1  mrg   /* Yay!  We're in a Libc that we understand, and it's made a
    337       1.1  mrg      system call.  In Jaguar, this is a direct system call with value 103;
    338       1.1  mrg      in Panther and Tiger it is a SYS_syscall call for system call number 184,
    339       1.1  mrg      and in Leopard it is a direct syscall with number 184.  */
    340       1.1  mrg 
    341       1.1  mrg   if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
    342       1.1  mrg     {
    343       1.1  mrg       uctx = (struct gcc_ucontext *) gprs[3];
    344       1.1  mrg       is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
    345       1.1  mrg 		   || uctx->mcsize == UC_FLAVOR_VEC_SIZE);
    346       1.1  mrg       is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
    347       1.1  mrg 	       || uctx->mcsize == UC_FLAVOR64_SIZE);
    348       1.1  mrg     }
    349       1.1  mrg   else if (gprs[0] == 0 /* SYS_syscall */ && gprs[3] == 184)
    350       1.1  mrg     {
    351       1.1  mrg       int ctxstyle = gprs[5];
    352       1.1  mrg       uctx = (struct gcc_ucontext *) gprs[4];
    353       1.1  mrg       is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
    354       1.1  mrg 		   || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
    355       1.1  mrg       is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
    356       1.1  mrg 	       || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
    357       1.1  mrg     }
    358       1.1  mrg   else if (gprs[0] == 184 /* SYS_sigreturn */)
    359       1.1  mrg     {
    360       1.1  mrg       int ctxstyle = gprs[4];
    361       1.1  mrg       uctx = (struct gcc_ucontext *) gprs[3];
    362       1.1  mrg       is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
    363       1.1  mrg 		   || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
    364       1.1  mrg       is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
    365       1.1  mrg 	       || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
    366       1.1  mrg     }
    367       1.1  mrg   else
    368       1.1  mrg     return false;
    369       1.1  mrg 
    370       1.1  mrg #define set_offset(r, addr)					\
    371  1.1.1.11  mrg   (fs->regs.how[r] = REG_SAVED_OFFSET,			\
    372       1.1  mrg    fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
    373       1.1  mrg 
    374       1.1  mrg   /* Restore even the registers that are not call-saved, since they
    375       1.1  mrg      might be being used in the prologue to save other registers,
    376       1.1  mrg      for instance GPR0 is sometimes used to save LR.  */
    377       1.1  mrg 
    378       1.1  mrg   /* Handle the GPRs, and produce the information needed to do the rest.  */
    379       1.1  mrg   if (is_64)
    380       1.1  mrg     {
    381       1.1  mrg       /* The context is 64-bit, but it doesn't carry any extra information
    382       1.1  mrg 	 for us because only the low 32 bits of the registers are
    383       1.1  mrg 	 call-saved.  */
    384       1.1  mrg       struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext;
    385       1.1  mrg       int i;
    386       1.1  mrg 
    387       1.1  mrg       float_vector_state = &m64->fvs;
    388       1.1  mrg 
    389       1.1  mrg       new_cfa = m64->gpr[1][1];
    390       1.1  mrg 
    391       1.1  mrg       set_offset (R_CR2, &m64->cr);
    392       1.1  mrg       for (i = 0; i < 32; i++)
    393       1.1  mrg 	set_offset (i, m64->gpr[i] + 1);
    394       1.1  mrg       set_offset (R_XER, m64->xer + 1);
    395       1.1  mrg       set_offset (R_LR, m64->lr + 1);
    396       1.1  mrg       set_offset (R_CTR, m64->ctr + 1);
    397       1.1  mrg       if (is_vector)
    398       1.1  mrg 	set_offset (R_VRSAVE, &m64->vrsave);
    399       1.1  mrg 
    400       1.1  mrg       /* Sometimes, srr0 points to the instruction that caused the exception,
    401       1.1  mrg 	 and sometimes to the next instruction to be executed; we want
    402       1.1  mrg 	 the latter.  */
    403       1.1  mrg       if (m64->exception == 3 || m64->exception == 4
    404       1.1  mrg 	  || m64->exception == 6
    405       1.1  mrg 	  || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
    406       1.1  mrg 	return_addr = m64->srr0 + 4;
    407       1.1  mrg       else
    408       1.1  mrg 	return_addr = m64->srr0;
    409       1.1  mrg     }
    410       1.1  mrg   else
    411       1.1  mrg     {
    412       1.1  mrg       struct gcc_mcontext32 *m = uctx->mcontext;
    413       1.1  mrg       int i;
    414       1.1  mrg 
    415       1.1  mrg       float_vector_state = &m->fvs;
    416       1.1  mrg 
    417       1.1  mrg       new_cfa = m->gpr[1];
    418       1.1  mrg 
    419       1.1  mrg       set_offset (R_CR2, &m->cr);
    420       1.1  mrg       for (i = 0; i < 32; i++)
    421       1.1  mrg 	set_offset (i, m->gpr + i);
    422       1.1  mrg       set_offset (R_XER, &m->xer);
    423       1.1  mrg       set_offset (R_LR, &m->lr);
    424       1.1  mrg       set_offset (R_CTR, &m->ctr);
    425       1.1  mrg 
    426       1.1  mrg       if (is_vector)
    427       1.1  mrg 	set_offset (R_VRSAVE, &m->vrsave);
    428       1.1  mrg 
    429       1.1  mrg       /* Sometimes, srr0 points to the instruction that caused the exception,
    430       1.1  mrg 	 and sometimes to the next instruction to be executed; we want
    431       1.1  mrg 	 the latter.  */
    432       1.1  mrg       if (m->exception == 3 || m->exception == 4
    433       1.1  mrg 	  || m->exception == 6
    434       1.1  mrg 	  || (m->exception == 7 && !(m->srr1 & 0x10000)))
    435       1.1  mrg 	return_addr = m->srr0 + 4;
    436       1.1  mrg       else
    437       1.1  mrg 	return_addr = m->srr0;
    438       1.1  mrg     }
    439       1.1  mrg 
    440       1.1  mrg   fs->regs.cfa_how = CFA_REG_OFFSET;
    441   1.1.1.2  mrg   fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
    442       1.1  mrg   fs->regs.cfa_offset = new_cfa - old_cfa;;
    443       1.1  mrg 
    444       1.1  mrg   /* The choice of column for the return address is somewhat tricky.
    445       1.1  mrg      Fortunately, the actual choice is private to this file, and
    446       1.1  mrg      the space it's reserved from is the GCC register space, not the
    447       1.1  mrg      DWARF2 numbering.  So any free element of the right size is an OK
    448       1.1  mrg      choice.  Thus: */
    449       1.1  mrg   fs->retaddr_column = ARG_POINTER_REGNUM;
    450       1.1  mrg   /* FIXME: this should really be done using a DWARF2 location expression,
    451       1.1  mrg      not using a static variable.  In fact, this entire file should
    452       1.1  mrg      be implemented in DWARF2 expressions.  */
    453       1.1  mrg   set_offset (ARG_POINTER_REGNUM, &return_addr);
    454       1.1  mrg 
    455       1.1  mrg   for (i = 0; i < 32; i++)
    456       1.1  mrg     set_offset (32 + i, float_vector_state->fpregs + i);
    457       1.1  mrg   set_offset (R_SPEFSCR, &float_vector_state->fpscr);
    458       1.1  mrg 
    459       1.1  mrg   if (is_vector)
    460       1.1  mrg     {
    461       1.1  mrg       for (i = 0; i < 32; i++)
    462       1.1  mrg 	set_offset (R_VR0 + i, float_vector_state->save_vr + i);
    463       1.1  mrg       set_offset (R_VSCR, float_vector_state->save_vscr);
    464       1.1  mrg     }
    465       1.1  mrg 
    466       1.1  mrg   return true;
    467       1.1  mrg }
    468       1.1  mrg 
    469       1.1  mrg /* This is also prototyped in rs6000/darwin.h, inside the
    470       1.1  mrg    MD_FALLBACK_FRAME_STATE_FOR macro.  */
    471       1.1  mrg extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
    472       1.1  mrg 					      _Unwind_FrameState *fs);
    473       1.1  mrg 
    474       1.1  mrg /* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
    475       1.1  mrg    returning true iff the frame was a sigreturn() frame that we
    476       1.1  mrg    can understand.  */
    477       1.1  mrg 
    478       1.1  mrg bool
    479       1.1  mrg _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
    480       1.1  mrg 				  _Unwind_FrameState *fs)
    481       1.1  mrg {
    482       1.1  mrg   reg_unit gprs[32];
    483       1.1  mrg 
    484       1.1  mrg   if (!interpret_libc (gprs, context))
    485       1.1  mrg     return false;
    486       1.1  mrg   return handle_syscall (fs, gprs, _Unwind_GetCFA (context));
    487       1.1  mrg }
    488       1.1  mrg #endif
    489