(root)/
glibc-2.38/
sysdeps/
generic/
unwind-dw2.c
       1  /* DWARF2 exception handling and frame unwind runtime interface routines.
       2     Copyright (C) 1997-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of the GNU C Library.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library 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 GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library; if not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  #ifdef _LIBC
      21  #include <stdlib.h>
      22  #include <string.h>
      23  #include <error.h>
      24  #include <libintl.h>
      25  #include <dwarf2.h>
      26  #include <stdio.h>
      27  #include <unwind.h>
      28  #include <unwind-pe.h>
      29  #include <unwind-dw2-fde.h>
      30  #else
      31  #include "tconfig.h"
      32  #include "tsystem.h"
      33  #include "dwarf2.h"
      34  #include "unwind.h"
      35  #include "unwind-pe.h"
      36  #include "unwind-dw2-fde.h"
      37  #include "gthr.h"
      38  #endif
      39  
      40  
      41  
      42  #ifndef STACK_GROWS_DOWNWARD
      43  #define STACK_GROWS_DOWNWARD 0
      44  #else
      45  #undef STACK_GROWS_DOWNWARD
      46  #define STACK_GROWS_DOWNWARD 1
      47  #endif
      48  
      49  /* A target can override (perhaps for backward compatibility) how
      50     many dwarf2 columns are unwound.  */
      51  #ifndef DWARF_FRAME_REGISTERS
      52  #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
      53  #endif
      54  
      55  /* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
      56  #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
      57  #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
      58  #endif
      59  
      60  /* This is the register and unwind state for a particular frame.  This
      61     provides the information necessary to unwind up past a frame and return
      62     to its caller.  */
      63  struct _Unwind_Context
      64  {
      65    void *reg[DWARF_FRAME_REGISTERS+1];
      66    void *cfa;
      67    void *ra;
      68    void *lsda;
      69    struct dwarf_eh_bases bases;
      70    _Unwind_Word args_size;
      71  };
      72  
      73  #ifndef _LIBC
      74  /* Byte size of every register managed by these routines.  */
      75  static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
      76  #endif
      77  
      78  
      79  /* The result of interpreting the frame unwind info for a frame.
      80     This is all symbolic at this point, as none of the values can
      81     be resolved until the target pc is located.  */
      82  typedef struct
      83  {
      84    /* Each register save state can be described in terms of a CFA slot,
      85       another register, or a location expression.  */
      86    struct frame_state_reg_info
      87    {
      88      struct {
      89        union {
      90  	_Unwind_Word reg;
      91  	_Unwind_Sword offset;
      92  	const unsigned char *exp;
      93        } loc;
      94        enum {
      95  	REG_UNSAVED,
      96  	REG_SAVED_OFFSET,
      97  	REG_SAVED_REG,
      98  	REG_SAVED_EXP,
      99        } how;
     100      } reg[DWARF_FRAME_REGISTERS+1];
     101  
     102      /* Used to implement DW_CFA_remember_state.  */
     103      struct frame_state_reg_info *prev;
     104    } regs;
     105  
     106    /* The CFA can be described in terms of a reg+offset or a
     107       location expression.  */
     108    _Unwind_Sword cfa_offset;
     109    _Unwind_Word cfa_reg;
     110    const unsigned char *cfa_exp;
     111    enum {
     112      CFA_UNSET,
     113      CFA_REG_OFFSET,
     114      CFA_EXP,
     115    } cfa_how;
     116  
     117    /* The PC described by the current frame state.  */
     118    void *pc;
     119  
     120    /* The information we care about from the CIE/FDE.  */
     121    _Unwind_Personality_Fn personality;
     122    _Unwind_Sword data_align;
     123    _Unwind_Word code_align;
     124    unsigned char retaddr_column;
     125    unsigned char fde_encoding;
     126    unsigned char lsda_encoding;
     127    unsigned char saw_z;
     128    void *eh_ptr;
     129  } _Unwind_FrameState;
     130  
     131  /* Read unaligned data from the instruction buffer.  */
     132  
     133  union unaligned
     134  {
     135    void *p;
     136    unsigned u2 __attribute__ ((mode (HI)));
     137    unsigned u4 __attribute__ ((mode (SI)));
     138    unsigned u8 __attribute__ ((mode (DI)));
     139    signed s2 __attribute__ ((mode (HI)));
     140    signed s4 __attribute__ ((mode (SI)));
     141    signed s8 __attribute__ ((mode (DI)));
     142  } __attribute__ ((packed));
     143  
     144  static inline void *
     145  read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
     146  
     147  static inline int
     148  read_1u (const void *p) { return *(const unsigned char *) p; }
     149  
     150  static inline int
     151  read_1s (const void *p) { return *(const signed char *) p; }
     152  
     153  static inline int
     154  read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
     155  
     156  static inline int
     157  read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
     158  
     159  static inline unsigned int
     160  read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
     161  
     162  static inline int
     163  read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
     164  
     165  static inline unsigned long
     166  read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
     167  
     168  static inline unsigned long
     169  read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
     170  
     171  /* Get the value of register REG as saved in CONTEXT.  */
     172  
     173  inline _Unwind_Word
     174  _Unwind_GetGR (struct _Unwind_Context *context, int index)
     175  {
     176    /* This will segfault if the register hasn't been saved.  */
     177    return * (_Unwind_Word *) context->reg[index];
     178  }
     179  
     180  /* Overwrite the saved value for register REG in CONTEXT with VAL.  */
     181  
     182  inline void
     183  _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
     184  {
     185    * (_Unwind_Word *) context->reg[index] = val;
     186  }
     187  
     188  /* Retrieve the return address for CONTEXT.  */
     189  
     190  inline _Unwind_Ptr
     191  _Unwind_GetIP (struct _Unwind_Context *context)
     192  {
     193    return (_Unwind_Ptr) context->ra;
     194  }
     195  
     196  /* Overwrite the return address for CONTEXT with VAL.  */
     197  
     198  inline void
     199  _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
     200  {
     201    context->ra = (void *) val;
     202  }
     203  
     204  void *
     205  _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
     206  {
     207    return context->lsda;
     208  }
     209  
     210  _Unwind_Ptr
     211  _Unwind_GetRegionStart (struct _Unwind_Context *context)
     212  {
     213    return (_Unwind_Ptr) context->bases.func;
     214  }
     215  
     216  void *
     217  _Unwind_FindEnclosingFunction (void *pc)
     218  {
     219    struct dwarf_eh_bases bases;
     220    struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
     221    if (fde)
     222      return bases.func;
     223    else
     224      return NULL;
     225  }
     226  
     227  #ifndef __ia64__
     228  _Unwind_Ptr
     229  _Unwind_GetDataRelBase (struct _Unwind_Context *context)
     230  {
     231    return (_Unwind_Ptr) context->bases.dbase;
     232  }
     233  
     234  _Unwind_Ptr
     235  _Unwind_GetTextRelBase (struct _Unwind_Context *context)
     236  {
     237    return (_Unwind_Ptr) context->bases.tbase;
     238  }
     239  #endif
     240  
     241  /* Extract any interesting information from the CIE for the translation
     242     unit F belongs to.  Return a pointer to the byte after the augmentation,
     243     or NULL if we encountered an undecipherable augmentation.  */
     244  
     245  static const unsigned char *
     246  extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
     247  		  _Unwind_FrameState *fs)
     248  {
     249    const unsigned char *aug = cie->augmentation;
     250    const unsigned char *p = aug + strlen ((const char *) aug) + 1;
     251    const unsigned char *ret = NULL;
     252    _Unwind_Word utmp;
     253  
     254    /* g++ v2 "eh" has pointer immediately following augmentation string,
     255       so it must be handled first.  */
     256    if (aug[0] == 'e' && aug[1] == 'h')
     257      {
     258        fs->eh_ptr = read_pointer (p);
     259        p += sizeof (void *);
     260        aug += 2;
     261      }
     262  
     263    /* Immediately following the augmentation are the code and
     264       data alignment and return address column.  */
     265    p = read_uleb128 (p, &fs->code_align);
     266    p = read_sleb128 (p, &fs->data_align);
     267    fs->retaddr_column = *p++;
     268    fs->lsda_encoding = DW_EH_PE_omit;
     269  
     270    /* If the augmentation starts with 'z', then a uleb128 immediately
     271       follows containing the length of the augmentation field following
     272       the size.  */
     273    if (*aug == 'z')
     274      {
     275        p = read_uleb128 (p, &utmp);
     276        ret = p + utmp;
     277  
     278        fs->saw_z = 1;
     279        ++aug;
     280      }
     281  
     282    /* Iterate over recognized augmentation subsequences.  */
     283    while (*aug != '\0')
     284      {
     285        /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
     286        if (aug[0] == 'L')
     287  	{
     288  	  fs->lsda_encoding = *p++;
     289  	  aug += 1;
     290  	}
     291  
     292        /* "R" indicates a byte indicating how FDE addresses are encoded.  */
     293        else if (aug[0] == 'R')
     294  	{
     295  	  fs->fde_encoding = *p++;
     296  	  aug += 1;
     297  	}
     298  
     299        /* "P" indicates a personality routine in the CIE augmentation.  */
     300        else if (aug[0] == 'P')
     301  	{
     302  	  _Unwind_Ptr personality;
     303  	  p = read_encoded_value (context, *p, p + 1, &personality);
     304  	  fs->personality = (_Unwind_Personality_Fn) personality;
     305  	  aug += 1;
     306  	}
     307  
     308        /* Otherwise we have an unknown augmentation string.
     309  	 Bail unless we saw a 'z' prefix.  */
     310        else
     311  	return ret;
     312      }
     313  
     314    return ret ? ret : p;
     315  }
     316  
     317  #ifndef _LIBC
     318  /* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
     319     onto the stack to start.  */
     320  
     321  static _Unwind_Word
     322  execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
     323  		  struct _Unwind_Context *context, _Unwind_Word initial)
     324  {
     325    _Unwind_Word stack[64];	/* ??? Assume this is enough.  */
     326    int stack_elt;
     327  
     328    stack[0] = initial;
     329    stack_elt = 1;
     330  
     331    while (op_ptr < op_end)
     332      {
     333        enum dwarf_location_atom op = *op_ptr++;
     334        _Unwind_Word result, reg, utmp;
     335        _Unwind_Sword offset, stmp;
     336  
     337        switch (op)
     338  	{
     339  	case DW_OP_lit0:
     340  	case DW_OP_lit1:
     341  	case DW_OP_lit2:
     342  	case DW_OP_lit3:
     343  	case DW_OP_lit4:
     344  	case DW_OP_lit5:
     345  	case DW_OP_lit6:
     346  	case DW_OP_lit7:
     347  	case DW_OP_lit8:
     348  	case DW_OP_lit9:
     349  	case DW_OP_lit10:
     350  	case DW_OP_lit11:
     351  	case DW_OP_lit12:
     352  	case DW_OP_lit13:
     353  	case DW_OP_lit14:
     354  	case DW_OP_lit15:
     355  	case DW_OP_lit16:
     356  	case DW_OP_lit17:
     357  	case DW_OP_lit18:
     358  	case DW_OP_lit19:
     359  	case DW_OP_lit20:
     360  	case DW_OP_lit21:
     361  	case DW_OP_lit22:
     362  	case DW_OP_lit23:
     363  	case DW_OP_lit24:
     364  	case DW_OP_lit25:
     365  	case DW_OP_lit26:
     366  	case DW_OP_lit27:
     367  	case DW_OP_lit28:
     368  	case DW_OP_lit29:
     369  	case DW_OP_lit30:
     370  	case DW_OP_lit31:
     371  	  result = op - DW_OP_lit0;
     372  	  break;
     373  
     374  	case DW_OP_addr:
     375  	  result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
     376  	  op_ptr += sizeof (void *);
     377  	  break;
     378  
     379  	case DW_OP_const1u:
     380  	  result = read_1u (op_ptr);
     381  	  op_ptr += 1;
     382  	  break;
     383  	case DW_OP_const1s:
     384  	  result = read_1s (op_ptr);
     385  	  op_ptr += 1;
     386  	  break;
     387  	case DW_OP_const2u:
     388  	  result = read_2u (op_ptr);
     389  	  op_ptr += 2;
     390  	  break;
     391  	case DW_OP_const2s:
     392  	  result = read_2s (op_ptr);
     393  	  op_ptr += 2;
     394  	  break;
     395  	case DW_OP_const4u:
     396  	  result = read_4u (op_ptr);
     397  	  op_ptr += 4;
     398  	  break;
     399  	case DW_OP_const4s:
     400  	  result = read_4s (op_ptr);
     401  	  op_ptr += 4;
     402  	  break;
     403  	case DW_OP_const8u:
     404  	  result = read_8u (op_ptr);
     405  	  op_ptr += 8;
     406  	  break;
     407  	case DW_OP_const8s:
     408  	  result = read_8s (op_ptr);
     409  	  op_ptr += 8;
     410  	  break;
     411  	case DW_OP_constu:
     412  	  op_ptr = read_uleb128 (op_ptr, &result);
     413  	  break;
     414  	case DW_OP_consts:
     415  	  op_ptr = read_sleb128 (op_ptr, &stmp);
     416  	  result = stmp;
     417  	  break;
     418  
     419  	case DW_OP_reg0:
     420  	case DW_OP_reg1:
     421  	case DW_OP_reg2:
     422  	case DW_OP_reg3:
     423  	case DW_OP_reg4:
     424  	case DW_OP_reg5:
     425  	case DW_OP_reg6:
     426  	case DW_OP_reg7:
     427  	case DW_OP_reg8:
     428  	case DW_OP_reg9:
     429  	case DW_OP_reg10:
     430  	case DW_OP_reg11:
     431  	case DW_OP_reg12:
     432  	case DW_OP_reg13:
     433  	case DW_OP_reg14:
     434  	case DW_OP_reg15:
     435  	case DW_OP_reg16:
     436  	case DW_OP_reg17:
     437  	case DW_OP_reg18:
     438  	case DW_OP_reg19:
     439  	case DW_OP_reg20:
     440  	case DW_OP_reg21:
     441  	case DW_OP_reg22:
     442  	case DW_OP_reg23:
     443  	case DW_OP_reg24:
     444  	case DW_OP_reg25:
     445  	case DW_OP_reg26:
     446  	case DW_OP_reg27:
     447  	case DW_OP_reg28:
     448  	case DW_OP_reg29:
     449  	case DW_OP_reg30:
     450  	case DW_OP_reg31:
     451  	  result = _Unwind_GetGR (context, op - DW_OP_reg0);
     452  	  break;
     453  	case DW_OP_regx:
     454  	  op_ptr = read_uleb128 (op_ptr, &reg);
     455  	  result = _Unwind_GetGR (context, reg);
     456  	  break;
     457  
     458  	case DW_OP_breg0:
     459  	case DW_OP_breg1:
     460  	case DW_OP_breg2:
     461  	case DW_OP_breg3:
     462  	case DW_OP_breg4:
     463  	case DW_OP_breg5:
     464  	case DW_OP_breg6:
     465  	case DW_OP_breg7:
     466  	case DW_OP_breg8:
     467  	case DW_OP_breg9:
     468  	case DW_OP_breg10:
     469  	case DW_OP_breg11:
     470  	case DW_OP_breg12:
     471  	case DW_OP_breg13:
     472  	case DW_OP_breg14:
     473  	case DW_OP_breg15:
     474  	case DW_OP_breg16:
     475  	case DW_OP_breg17:
     476  	case DW_OP_breg18:
     477  	case DW_OP_breg19:
     478  	case DW_OP_breg20:
     479  	case DW_OP_breg21:
     480  	case DW_OP_breg22:
     481  	case DW_OP_breg23:
     482  	case DW_OP_breg24:
     483  	case DW_OP_breg25:
     484  	case DW_OP_breg26:
     485  	case DW_OP_breg27:
     486  	case DW_OP_breg28:
     487  	case DW_OP_breg29:
     488  	case DW_OP_breg30:
     489  	case DW_OP_breg31:
     490  	  op_ptr = read_sleb128 (op_ptr, &offset);
     491  	  result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
     492  	  break;
     493  	case DW_OP_bregx:
     494  	  op_ptr = read_uleb128 (op_ptr, &reg);
     495  	  op_ptr = read_sleb128 (op_ptr, &offset);
     496  	  result = _Unwind_GetGR (context, reg) + offset;
     497  	  break;
     498  
     499  	case DW_OP_dup:
     500  	  if (stack_elt < 1)
     501  	    abort ();
     502  	  result = stack[stack_elt - 1];
     503  	  break;
     504  
     505  	case DW_OP_drop:
     506  	  if (--stack_elt < 0)
     507  	    abort ();
     508  	  goto no_push;
     509  
     510  	case DW_OP_pick:
     511  	  offset = *op_ptr++;
     512  	  if (offset >= stack_elt - 1)
     513  	    abort ();
     514  	  result = stack[stack_elt - 1 - offset];
     515  	  break;
     516  
     517  	case DW_OP_over:
     518  	  if (stack_elt < 2)
     519  	    abort ();
     520  	  result = stack[stack_elt - 2];
     521  	  break;
     522  
     523  	case DW_OP_rot:
     524  	  {
     525  	    _Unwind_Word t1, t2, t3;
     526  
     527  	    if (stack_elt < 3)
     528  	      abort ();
     529  	    t1 = stack[stack_elt - 1];
     530  	    t2 = stack[stack_elt - 2];
     531  	    t3 = stack[stack_elt - 3];
     532  	    stack[stack_elt - 1] = t2;
     533  	    stack[stack_elt - 2] = t3;
     534  	    stack[stack_elt - 3] = t1;
     535  	    goto no_push;
     536  	  }
     537  
     538  	case DW_OP_deref:
     539  	case DW_OP_deref_size:
     540  	case DW_OP_abs:
     541  	case DW_OP_neg:
     542  	case DW_OP_not:
     543  	case DW_OP_plus_uconst:
     544  	  /* Unary operations.  */
     545  	  if (--stack_elt < 0)
     546  	    abort ();
     547  	  result = stack[stack_elt];
     548  
     549  	  switch (op)
     550  	    {
     551  	    case DW_OP_deref:
     552  	      {
     553  		void *ptr = (void *) (_Unwind_Ptr) result;
     554  		result = (_Unwind_Ptr) read_pointer (ptr);
     555  	      }
     556  	      break;
     557  
     558  	    case DW_OP_deref_size:
     559  	      {
     560  		void *ptr = (void *) (_Unwind_Ptr) result;
     561  		switch (*op_ptr++)
     562  		  {
     563  		  case 1:
     564  		    result = read_1u (ptr);
     565  		    break;
     566  		  case 2:
     567  		    result = read_2u (ptr);
     568  		    break;
     569  		  case 4:
     570  		    result = read_4u (ptr);
     571  		    break;
     572  		  case 8:
     573  		    result = read_8u (ptr);
     574  		    break;
     575  		  default:
     576  		    abort ();
     577  		  }
     578  	      }
     579  	      break;
     580  
     581  	    case DW_OP_abs:
     582  	      if ((_Unwind_Sword) result < 0)
     583  		result = -result;
     584  	      break;
     585  	    case DW_OP_neg:
     586  	      result = -result;
     587  	      break;
     588  	    case DW_OP_not:
     589  	      result = ~result;
     590  	      break;
     591  	    case DW_OP_plus_uconst:
     592  	      op_ptr = read_uleb128 (op_ptr, &utmp);
     593  	      result += utmp;
     594  	      break;
     595  
     596  	    default:
     597  	      abort ();
     598  	    }
     599  	  break;
     600  
     601  	case DW_OP_and:
     602  	case DW_OP_div:
     603  	case DW_OP_minus:
     604  	case DW_OP_mod:
     605  	case DW_OP_mul:
     606  	case DW_OP_or:
     607  	case DW_OP_plus:
     608  	case DW_OP_le:
     609  	case DW_OP_ge:
     610  	case DW_OP_eq:
     611  	case DW_OP_lt:
     612  	case DW_OP_gt:
     613  	case DW_OP_ne:
     614  	  {
     615  	    /* Binary operations.  */
     616  	    _Unwind_Word first, second;
     617  	    if ((stack_elt -= 2) < 0)
     618  	      abort ();
     619  	    second = stack[stack_elt];
     620  	    first = stack[stack_elt + 1];
     621  
     622  	    switch (op)
     623  	      {
     624  	      case DW_OP_and:
     625  		result = second & first;
     626  		break;
     627  	      case DW_OP_div:
     628  		result = (_Unwind_Sword) second / (_Unwind_Sword) first;
     629  		break;
     630  	      case DW_OP_minus:
     631  		result = second - first;
     632  		break;
     633  	      case DW_OP_mod:
     634  		result = (_Unwind_Sword) second % (_Unwind_Sword) first;
     635  		break;
     636  	      case DW_OP_mul:
     637  		result = second * first;
     638  		break;
     639  	      case DW_OP_or:
     640  		result = second | first;
     641  		break;
     642  	      case DW_OP_plus:
     643  		result = second + first;
     644  		break;
     645  	      case DW_OP_shl:
     646  		result = second << first;
     647  		break;
     648  	      case DW_OP_shr:
     649  		result = second >> first;
     650  		break;
     651  	      case DW_OP_shra:
     652  		result = (_Unwind_Sword) second >> first;
     653  		break;
     654  	      case DW_OP_xor:
     655  		result = second ^ first;
     656  		break;
     657  	      case DW_OP_le:
     658  		result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
     659  		break;
     660  	      case DW_OP_ge:
     661  		result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
     662  		break;
     663  	      case DW_OP_eq:
     664  		result = (_Unwind_Sword) first == (_Unwind_Sword) second;
     665  		break;
     666  	      case DW_OP_lt:
     667  		result = (_Unwind_Sword) first < (_Unwind_Sword) second;
     668  		break;
     669  	      case DW_OP_gt:
     670  		result = (_Unwind_Sword) first > (_Unwind_Sword) second;
     671  		break;
     672  	      case DW_OP_ne:
     673  		result = (_Unwind_Sword) first != (_Unwind_Sword) second;
     674  		break;
     675  
     676  	      default:
     677  		abort ();
     678  	      }
     679  	  }
     680  	  break;
     681  
     682  	case DW_OP_skip:
     683  	  offset = read_2s (op_ptr);
     684  	  op_ptr += 2;
     685  	  op_ptr += offset;
     686  	  goto no_push;
     687  
     688  	case DW_OP_bra:
     689  	  if (--stack_elt < 0)
     690  	    abort ();
     691  	  offset = read_2s (op_ptr);
     692  	  op_ptr += 2;
     693  	  if (stack[stack_elt] != 0)
     694  	    op_ptr += offset;
     695  	  goto no_push;
     696  
     697  	case DW_OP_nop:
     698  	  goto no_push;
     699  
     700  	default:
     701  	  abort ();
     702  	}
     703  
     704        /* Most things push a result value.  */
     705        if ((size_t) stack_elt >= sizeof (stack) / sizeof (*stack))
     706  	abort ();
     707        stack[stack_elt++] = result;
     708      no_push:;
     709      }
     710  
     711    /* We were executing this program to get a value.  It should be
     712       at top of stack.  */
     713    if (--stack_elt < 0)
     714      abort ();
     715    return stack[stack_elt];
     716  }
     717  #endif
     718  
     719  /* Decode DWARF 2 call frame information. Takes pointers the
     720     instruction sequence to decode, current register information and
     721     CIE info, and the PC range to evaluate.  */
     722  
     723  static void
     724  execute_cfa_program (const unsigned char *insn_ptr,
     725  		     const unsigned char *insn_end,
     726  		     struct _Unwind_Context *context,
     727  		     _Unwind_FrameState *fs)
     728  {
     729    struct frame_state_reg_info *unused_rs = NULL;
     730  
     731    /* Don't allow remember/restore between CIE and FDE programs.  */
     732    fs->regs.prev = NULL;
     733  
     734    /* The comparison with the return address uses < rather than <= because
     735       we are only interested in the effects of code before the call; for a
     736       noreturn function, the return address may point to unrelated code with
     737       a different stack configuration that we are not interested in.  We
     738       assume that the call itself is unwind info-neutral; if not, or if
     739       there are delay instructions that adjust the stack, these must be
     740       reflected at the point immediately before the call insn.  */
     741    while (insn_ptr < insn_end && fs->pc < context->ra)
     742      {
     743        unsigned char insn = *insn_ptr++;
     744        _Unwind_Word reg, utmp;
     745        _Unwind_Sword offset, stmp;
     746  
     747        if ((insn & 0xc0) == DW_CFA_advance_loc)
     748  	fs->pc += (insn & 0x3f) * fs->code_align;
     749        else if ((insn & 0xc0) == DW_CFA_offset)
     750  	{
     751  	  reg = insn & 0x3f;
     752  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     753  	  offset = (_Unwind_Sword) utmp * fs->data_align;
     754  	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
     755  	  fs->regs.reg[reg].loc.offset = offset;
     756  	}
     757        else if ((insn & 0xc0) == DW_CFA_restore)
     758  	{
     759  	  reg = insn & 0x3f;
     760  	  fs->regs.reg[reg].how = REG_UNSAVED;
     761  	}
     762        else switch (insn)
     763  	{
     764  	case DW_CFA_set_loc:
     765  	  {
     766  	    _Unwind_Ptr pc;
     767  	    insn_ptr = read_encoded_value (context, fs->fde_encoding,
     768  					   insn_ptr, &pc);
     769  	    fs->pc = (void *) pc;
     770  	  }
     771  	  break;
     772  
     773  	case DW_CFA_advance_loc1:
     774  	  fs->pc += read_1u (insn_ptr) * fs->code_align;
     775  	  insn_ptr += 1;
     776  	  break;
     777  	case DW_CFA_advance_loc2:
     778  	  fs->pc += read_2u (insn_ptr) * fs->code_align;
     779  	  insn_ptr += 2;
     780  	  break;
     781  	case DW_CFA_advance_loc4:
     782  	  fs->pc += read_4u (insn_ptr) * fs->code_align;
     783  	  insn_ptr += 4;
     784  	  break;
     785  
     786  	case DW_CFA_offset_extended:
     787  	  insn_ptr = read_uleb128 (insn_ptr, &reg);
     788  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     789  	  offset = (_Unwind_Sword) utmp * fs->data_align;
     790  	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
     791  	  fs->regs.reg[reg].loc.offset = offset;
     792  	  break;
     793  
     794  	case DW_CFA_restore_extended:
     795  	  insn_ptr = read_uleb128 (insn_ptr, &reg);
     796  	  fs->regs.reg[reg].how = REG_UNSAVED;
     797  	  break;
     798  
     799  	case DW_CFA_undefined:
     800  	case DW_CFA_same_value:
     801  	  insn_ptr = read_uleb128 (insn_ptr, &reg);
     802  	  break;
     803  
     804  	case DW_CFA_nop:
     805  	  break;
     806  
     807  	case DW_CFA_register:
     808  	  {
     809  	    _Unwind_Word reg2;
     810  	    insn_ptr = read_uleb128 (insn_ptr, &reg);
     811  	    insn_ptr = read_uleb128 (insn_ptr, &reg2);
     812  	    fs->regs.reg[reg].how = REG_SAVED_REG;
     813  	    fs->regs.reg[reg].loc.reg = reg2;
     814  	  }
     815  	  break;
     816  
     817  	case DW_CFA_remember_state:
     818  	  {
     819  	    struct frame_state_reg_info *new_rs;
     820  	    if (unused_rs)
     821  	      {
     822  		new_rs = unused_rs;
     823  		unused_rs = unused_rs->prev;
     824  	      }
     825  	    else
     826  	      new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
     827  
     828  	    *new_rs = fs->regs;
     829  	    fs->regs.prev = new_rs;
     830  	  }
     831  	  break;
     832  
     833  	case DW_CFA_restore_state:
     834  	  {
     835  	    struct frame_state_reg_info *old_rs = fs->regs.prev;
     836  #ifdef _LIBC
     837  	    if (old_rs == NULL)
     838  	      __libc_fatal ("Invalid DWARF unwind data.\n");
     839  	    else
     840  #endif
     841  	      {
     842  		fs->regs = *old_rs;
     843  		old_rs->prev = unused_rs;
     844  		unused_rs = old_rs;
     845  	      }
     846  	  }
     847  	  break;
     848  
     849  	case DW_CFA_def_cfa:
     850  	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
     851  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     852  	  fs->cfa_offset = utmp;
     853  	  fs->cfa_how = CFA_REG_OFFSET;
     854  	  break;
     855  
     856  	case DW_CFA_def_cfa_register:
     857  	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
     858  	  fs->cfa_how = CFA_REG_OFFSET;
     859  	  break;
     860  
     861  	case DW_CFA_def_cfa_offset:
     862  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     863  	  fs->cfa_offset = utmp;
     864  	  /* cfa_how deliberately not set.  */
     865  	  break;
     866  
     867  	case DW_CFA_def_cfa_expression:
     868  	  fs->cfa_exp = insn_ptr;
     869  	  fs->cfa_how = CFA_EXP;
     870  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     871  	  insn_ptr += utmp;
     872  	  break;
     873  
     874  	case DW_CFA_expression:
     875  	  insn_ptr = read_uleb128 (insn_ptr, &reg);
     876  	  fs->regs.reg[reg].how = REG_SAVED_EXP;
     877  	  fs->regs.reg[reg].loc.exp = insn_ptr;
     878  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     879  	  insn_ptr += utmp;
     880  	  break;
     881  
     882  	  /* From the 2.1 draft.  */
     883  	case DW_CFA_offset_extended_sf:
     884  	  insn_ptr = read_uleb128 (insn_ptr, &reg);
     885  	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
     886  	  offset = stmp * fs->data_align;
     887  	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
     888  	  fs->regs.reg[reg].loc.offset = offset;
     889  	  break;
     890  
     891  	case DW_CFA_def_cfa_sf:
     892  	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
     893  	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
     894  	  fs->cfa_how = CFA_REG_OFFSET;
     895  	  break;
     896  
     897  	case DW_CFA_def_cfa_offset_sf:
     898  	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
     899  	  /* cfa_how deliberately not set.  */
     900  	  break;
     901  
     902  	case DW_CFA_GNU_window_save:
     903  	  /* ??? Hardcoded for SPARC register window configuration.
     904  	     At least do not do anything for archs which explicitly
     905  	     define a lower register number.  */
     906  #if DWARF_FRAME_REGISTERS >= 32
     907  	  for (reg = 16; reg < 32; ++reg)
     908  	    {
     909  	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
     910  	      fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
     911  	    }
     912  #endif
     913  	  break;
     914  
     915  	case DW_CFA_GNU_args_size:
     916  	  insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
     917  	  break;
     918  
     919  	case DW_CFA_GNU_negative_offset_extended:
     920  	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
     921  	     older PowerPC code.  */
     922  	  insn_ptr = read_uleb128 (insn_ptr, &reg);
     923  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
     924  	  offset = (_Unwind_Word) utmp * fs->data_align;
     925  	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
     926  	  fs->regs.reg[reg].loc.offset = -offset;
     927  	  break;
     928  
     929  	default:
     930  	  abort ();
     931  	}
     932      }
     933  }
     934  
     935  /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
     936     its caller and decode it into FS.  This function also sets the
     937     args_size and lsda members of CONTEXT, as they are really information
     938     about the caller's frame.  */
     939  
     940  static _Unwind_Reason_Code
     941  uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
     942  {
     943    struct dwarf_fde *fde;
     944    struct dwarf_cie *cie;
     945    const unsigned char *aug, *insn, *end;
     946  
     947    memset (fs, 0, sizeof (*fs));
     948    context->args_size = 0;
     949    context->lsda = 0;
     950  
     951    fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
     952    if (fde == NULL)
     953      {
     954        /* Couldn't find frame unwind info for this function.  Try a
     955  	 target-specific fallback mechanism.  This will necessarily
     956  	 not provide a personality routine or LSDA.  */
     957  #ifdef MD_FALLBACK_FRAME_STATE_FOR
     958        MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
     959        return _URC_END_OF_STACK;
     960      success:
     961        return _URC_NO_REASON;
     962  #else
     963        return _URC_END_OF_STACK;
     964  #endif
     965      }
     966  
     967    fs->pc = context->bases.func;
     968  
     969    cie = get_cie (fde);
     970    insn = extract_cie_info (cie, context, fs);
     971    if (insn == NULL)
     972      /* CIE contained unknown augmentation.  */
     973      return _URC_FATAL_PHASE1_ERROR;
     974  
     975    /* First decode all the insns in the CIE.  */
     976    end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
     977    execute_cfa_program (insn, end, context, fs);
     978  
     979    /* Locate augmentation for the fde.  */
     980    aug = (unsigned char *) fde + sizeof (*fde);
     981    aug += 2 * size_of_encoded_value (fs->fde_encoding);
     982    insn = NULL;
     983    if (fs->saw_z)
     984      {
     985        _Unwind_Word i;
     986        aug = read_uleb128 (aug, &i);
     987        insn = aug + i;
     988      }
     989    if (fs->lsda_encoding != DW_EH_PE_omit)
     990      {
     991        _Unwind_Ptr lsda;
     992        aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
     993        context->lsda = (void *) lsda;
     994      }
     995  
     996    /* Then the insns in the FDE up to our target PC.  */
     997    if (insn == NULL)
     998      insn = aug;
     999    end = (unsigned char *) next_fde (fde);
    1000    execute_cfa_program (insn, end, context, fs);
    1001  
    1002    return _URC_NO_REASON;
    1003  }
    1004  
    1005  typedef struct frame_state
    1006  {
    1007    void *cfa;
    1008    void *eh_ptr;
    1009    long cfa_offset;
    1010    long args_size;
    1011    long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
    1012    unsigned short cfa_reg;
    1013    unsigned short retaddr_column;
    1014    char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
    1015  } frame_state;
    1016  
    1017  #ifndef STATIC
    1018  # define STATIC
    1019  #endif
    1020  
    1021  STATIC
    1022  struct frame_state * __frame_state_for (void *, struct frame_state *);
    1023  
    1024  /* Called from pre-G++ 3.0 __throw to find the registers to restore for
    1025     a given PC_TARGET.  The caller should allocate a local variable of
    1026     `struct frame_state' and pass its address to STATE_IN.  */
    1027  
    1028  STATIC
    1029  struct frame_state *
    1030  __frame_state_for (void *pc_target, struct frame_state *state_in)
    1031  {
    1032    struct _Unwind_Context context;
    1033    _Unwind_FrameState fs;
    1034    int reg;
    1035  
    1036    memset (&context, 0, sizeof (struct _Unwind_Context));
    1037    context.ra = pc_target + 1;
    1038  
    1039    if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
    1040      return 0;
    1041  
    1042    /* We have no way to pass a location expression for the CFA to our
    1043       caller.  It wouldn't understand it anyway.  */
    1044    if (fs.cfa_how == CFA_EXP)
    1045      return 0;
    1046  
    1047    for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
    1048      {
    1049        state_in->saved[reg] = fs.regs.reg[reg].how;
    1050        switch (state_in->saved[reg])
    1051  	{
    1052  	case REG_SAVED_REG:
    1053  	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
    1054  	  break;
    1055  	case REG_SAVED_OFFSET:
    1056  	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
    1057  	  break;
    1058  	default:
    1059  	  state_in->reg_or_offset[reg] = 0;
    1060  	  break;
    1061  	}
    1062      }
    1063  
    1064    state_in->cfa_offset = fs.cfa_offset;
    1065    state_in->cfa_reg = fs.cfa_reg;
    1066    state_in->retaddr_column = fs.retaddr_column;
    1067    state_in->args_size = context.args_size;
    1068    state_in->eh_ptr = fs.eh_ptr;
    1069  
    1070    return state_in;
    1071  }
    1072  
    1073  #ifndef _LIBC
    1074  
    1075  static void
    1076  uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
    1077  {
    1078    struct _Unwind_Context orig_context = *context;
    1079    void *cfa;
    1080    long i;
    1081  
    1082  #ifdef EH_RETURN_STACKADJ_RTX
    1083    /* Special handling here: Many machines do not use a frame pointer,
    1084       and track the CFA only through offsets from the stack pointer from
    1085       one frame to the next.  In this case, the stack pointer is never
    1086       stored, so it has no saved address in the context.  What we do
    1087       have is the CFA from the previous stack frame.
    1088  
    1089       In very special situations (such as unwind info for signal return),
    1090       there may be location expressions that use the stack pointer as well.
    1091  
    1092       Do this conditionally for one frame.  This allows the unwind info
    1093       for one frame to save a copy of the stack pointer from the previous
    1094       frame, and be able to use much easier CFA mechanisms to do it.
    1095       Always zap the saved stack pointer value for the next frame; carrying
    1096       the value over from one frame to another doesn't make sense.  */
    1097  
    1098    _Unwind_Word tmp_sp;
    1099  
    1100    if (!orig_context.reg[__builtin_dwarf_sp_column ()])
    1101      {
    1102        tmp_sp = (_Unwind_Ptr) context->cfa;
    1103        orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
    1104      }
    1105    context->reg[__builtin_dwarf_sp_column ()] = NULL;
    1106  #endif
    1107  
    1108    /* Compute this frame's CFA.  */
    1109    switch (fs->cfa_how)
    1110      {
    1111      case CFA_REG_OFFSET:
    1112        cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
    1113        cfa += fs->cfa_offset;
    1114        break;
    1115  
    1116      case CFA_EXP:
    1117        {
    1118  	const unsigned char *exp = fs->cfa_exp;
    1119  	_Unwind_Word len;
    1120  
    1121  	exp = read_uleb128 (exp, &len);
    1122  	cfa = (void *) (_Unwind_Ptr)
    1123  	  execute_stack_op (exp, exp + len, &orig_context, 0);
    1124  	break;
    1125        }
    1126  
    1127      default:
    1128        abort ();
    1129      }
    1130    context->cfa = cfa;
    1131  
    1132    /* Compute the addresses of all registers saved in this frame.  */
    1133    for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
    1134      switch (fs->regs.reg[i].how)
    1135        {
    1136        case REG_UNSAVED:
    1137  	break;
    1138  
    1139        case REG_SAVED_OFFSET:
    1140  	context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
    1141  	break;
    1142  
    1143        case REG_SAVED_REG:
    1144  	context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
    1145  	break;
    1146  
    1147        case REG_SAVED_EXP:
    1148  	{
    1149  	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
    1150  	  _Unwind_Word len;
    1151  	  _Unwind_Ptr val;
    1152  
    1153  	  exp = read_uleb128 (exp, &len);
    1154  	  val = execute_stack_op (exp, exp + len, &orig_context,
    1155  				  (_Unwind_Ptr) cfa);
    1156  	  context->reg[i] = (void *) val;
    1157  	}
    1158  	break;
    1159        }
    1160  }
    1161  
    1162  /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
    1163     of its caller.  Update CONTEXT to refer to the caller as well.  Note
    1164     that the args_size and lsda members are not updated here, but later in
    1165     uw_frame_state_for.  */
    1166  
    1167  static void
    1168  uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
    1169  {
    1170    uw_update_context_1 (context, fs);
    1171  
    1172    /* Compute the return address now, since the return address column
    1173       can change from frame to frame.  */
    1174    context->ra = __builtin_extract_return_addr
    1175      ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
    1176  }
    1177  
    1178  /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
    1179     level will be the return address and the CFA.  */
    1180  
    1181  #define uw_init_context(CONTEXT)					   \
    1182    do									   \
    1183      {									   \
    1184        /* Do any necessary initialization to access arbitrary stack frames. \
    1185  	 On the SPARC, this means flushing the register windows.  */	   \
    1186        __builtin_unwind_init ();						   \
    1187        uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),		   \
    1188  			 __builtin_return_address (0));			   \
    1189      }									   \
    1190    while (0)
    1191  
    1192  static void
    1193  uw_init_context_1 (struct _Unwind_Context *context,
    1194  		   void *outer_cfa, void *outer_ra)
    1195  {
    1196    void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
    1197    _Unwind_FrameState fs;
    1198    _Unwind_Word sp_slot;
    1199  
    1200    memset (context, 0, sizeof (struct _Unwind_Context));
    1201    context->ra = ra;
    1202  
    1203    if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
    1204      abort ();
    1205  
    1206    /* Force the frame state to use the known cfa value.  */
    1207    sp_slot = (_Unwind_Ptr) outer_cfa;
    1208    context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
    1209    fs.cfa_how = CFA_REG_OFFSET;
    1210    fs.cfa_reg = __builtin_dwarf_sp_column ();
    1211    fs.cfa_offset = 0;
    1212  
    1213    uw_update_context_1 (context, &fs);
    1214  
    1215    /* If the return address column was saved in a register in the
    1216       initialization context, then we can't see it in the given
    1217       call frame data.  So have the initialization context tell us.  */
    1218    context->ra = __builtin_extract_return_addr (outer_ra);
    1219  }
    1220  
    1221  
    1222  /* Install TARGET into CURRENT so that we can return to it.  This is a
    1223     macro because __builtin_eh_return must be invoked in the context of
    1224     our caller.  */
    1225  
    1226  #define uw_install_context(CURRENT, TARGET)				 \
    1227    do									 \
    1228      {									 \
    1229        long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
    1230        void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
    1231        __builtin_eh_return (offset, handler);				 \
    1232      }									 \
    1233    while (0)
    1234  
    1235  static inline void
    1236  init_dwarf_reg_size_table (void)
    1237  {
    1238    __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
    1239  }
    1240  
    1241  static long
    1242  uw_install_context_1 (struct _Unwind_Context *current,
    1243  		      struct _Unwind_Context *target)
    1244  {
    1245    long i;
    1246  
    1247  #if __GTHREADS
    1248    {
    1249      static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
    1250      if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
    1251  	|| dwarf_reg_size_table[0] == 0)
    1252        init_dwarf_reg_size_table ();
    1253    }
    1254  #else
    1255    if (dwarf_reg_size_table[0] == 0)
    1256      init_dwarf_reg_size_table ();
    1257  #endif
    1258  
    1259    for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
    1260      {
    1261        void *c = current->reg[i];
    1262        void *t = target->reg[i];
    1263        if (t && c && t != c)
    1264  	memcpy (c, t, dwarf_reg_size_table[i]);
    1265      }
    1266  
    1267  #ifdef EH_RETURN_STACKADJ_RTX
    1268    {
    1269      void *target_cfa;
    1270  
    1271      /* If the last frame records a saved stack pointer, use it.  */
    1272      if (target->reg[__builtin_dwarf_sp_column ()])
    1273        target_cfa = (void *)(_Unwind_Ptr)
    1274          _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
    1275      else
    1276        target_cfa = target->cfa;
    1277  
    1278      /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
    1279      if (STACK_GROWS_DOWNWARD)
    1280        return target_cfa - current->cfa + target->args_size;
    1281      else
    1282        return current->cfa - target_cfa - target->args_size;
    1283    }
    1284  #else
    1285    return 0;
    1286  #endif
    1287  }
    1288  
    1289  static inline _Unwind_Ptr
    1290  uw_identify_context (struct _Unwind_Context *context)
    1291  {
    1292    return _Unwind_GetIP (context);
    1293  }
    1294  
    1295  
    1296  #include "unwind.inc"
    1297  
    1298  #endif /* _LIBC */