Blame sysdeps/generic/unwind-dw2.c

Packit Service 82fcde
/* DWARF2 exception handling and frame unwind runtime interface routines.
Packit Service 82fcde
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit Service 82fcde
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <error.h>
Packit Service 82fcde
#include <libintl.h>
Packit Service 82fcde
#include <dwarf2.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <unwind.h>
Packit Service 82fcde
#include <unwind-pe.h>
Packit Service 82fcde
#include <unwind-dw2-fde.h>
Packit Service 82fcde
#else
Packit Service 82fcde
#include "tconfig.h"
Packit Service 82fcde
#include "tsystem.h"
Packit Service 82fcde
#include "dwarf2.h"
Packit Service 82fcde
#include "unwind.h"
Packit Service 82fcde
#include "unwind-pe.h"
Packit Service 82fcde
#include "unwind-dw2-fde.h"
Packit Service 82fcde
#include "gthr.h"
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#ifndef STACK_GROWS_DOWNWARD
Packit Service 82fcde
#define STACK_GROWS_DOWNWARD 0
Packit Service 82fcde
#else
Packit Service 82fcde
#undef STACK_GROWS_DOWNWARD
Packit Service 82fcde
#define STACK_GROWS_DOWNWARD 1
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* A target can override (perhaps for backward compatibility) how
Packit Service 82fcde
   many dwarf2 columns are unwound.  */
Packit Service 82fcde
#ifndef DWARF_FRAME_REGISTERS
Packit Service 82fcde
#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
Packit Service 82fcde
#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
Packit Service 82fcde
#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* This is the register and unwind state for a particular frame.  This
Packit Service 82fcde
   provides the information necessary to unwind up past a frame and return
Packit Service 82fcde
   to its caller.  */
Packit Service 82fcde
struct _Unwind_Context
Packit Service 82fcde
{
Packit Service 82fcde
  void *reg[DWARF_FRAME_REGISTERS+1];
Packit Service 82fcde
  void *cfa;
Packit Service 82fcde
  void *ra;
Packit Service 82fcde
  void *lsda;
Packit Service 82fcde
  struct dwarf_eh_bases bases;
Packit Service 82fcde
  _Unwind_Word args_size;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
#ifndef _LIBC
Packit Service 82fcde
/* Byte size of every register managed by these routines.  */
Packit Service 82fcde
static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde

Packit Service 82fcde
/* The result of interpreting the frame unwind info for a frame.
Packit Service 82fcde
   This is all symbolic at this point, as none of the values can
Packit Service 82fcde
   be resolved until the target pc is located.  */
Packit Service 82fcde
typedef struct
Packit Service 82fcde
{
Packit Service 82fcde
  /* Each register save state can be described in terms of a CFA slot,
Packit Service 82fcde
     another register, or a location expression.  */
Packit Service 82fcde
  struct frame_state_reg_info
Packit Service 82fcde
  {
Packit Service 82fcde
    struct {
Packit Service 82fcde
      union {
Packit Service 82fcde
	_Unwind_Word reg;
Packit Service 82fcde
	_Unwind_Sword offset;
Packit Service 82fcde
	const unsigned char *exp;
Packit Service 82fcde
      } loc;
Packit Service 82fcde
      enum {
Packit Service 82fcde
	REG_UNSAVED,
Packit Service 82fcde
	REG_SAVED_OFFSET,
Packit Service 82fcde
	REG_SAVED_REG,
Packit Service 82fcde
	REG_SAVED_EXP,
Packit Service 82fcde
      } how;
Packit Service 82fcde
    } reg[DWARF_FRAME_REGISTERS+1];
Packit Service 82fcde
Packit Service 82fcde
    /* Used to implement DW_CFA_remember_state.  */
Packit Service 82fcde
    struct frame_state_reg_info *prev;
Packit Service 82fcde
  } regs;
Packit Service 82fcde
Packit Service 82fcde
  /* The CFA can be described in terms of a reg+offset or a
Packit Service 82fcde
     location expression.  */
Packit Service 82fcde
  _Unwind_Sword cfa_offset;
Packit Service 82fcde
  _Unwind_Word cfa_reg;
Packit Service 82fcde
  const unsigned char *cfa_exp;
Packit Service 82fcde
  enum {
Packit Service 82fcde
    CFA_UNSET,
Packit Service 82fcde
    CFA_REG_OFFSET,
Packit Service 82fcde
    CFA_EXP,
Packit Service 82fcde
  } cfa_how;
Packit Service 82fcde
Packit Service 82fcde
  /* The PC described by the current frame state.  */
Packit Service 82fcde
  void *pc;
Packit Service 82fcde
Packit Service 82fcde
  /* The information we care about from the CIE/FDE.  */
Packit Service 82fcde
  _Unwind_Personality_Fn personality;
Packit Service 82fcde
  _Unwind_Sword data_align;
Packit Service 82fcde
  _Unwind_Word code_align;
Packit Service 82fcde
  unsigned char retaddr_column;
Packit Service 82fcde
  unsigned char fde_encoding;
Packit Service 82fcde
  unsigned char lsda_encoding;
Packit Service 82fcde
  unsigned char saw_z;
Packit Service 82fcde
  void *eh_ptr;
Packit Service 82fcde
} _Unwind_FrameState;
Packit Service 82fcde

Packit Service 82fcde
/* Read unaligned data from the instruction buffer.  */
Packit Service 82fcde
Packit Service 82fcde
union unaligned
Packit Service 82fcde
{
Packit Service 82fcde
  void *p;
Packit Service 82fcde
  unsigned u2 __attribute__ ((mode (HI)));
Packit Service 82fcde
  unsigned u4 __attribute__ ((mode (SI)));
Packit Service 82fcde
  unsigned u8 __attribute__ ((mode (DI)));
Packit Service 82fcde
  signed s2 __attribute__ ((mode (HI)));
Packit Service 82fcde
  signed s4 __attribute__ ((mode (SI)));
Packit Service 82fcde
  signed s8 __attribute__ ((mode (DI)));
Packit Service 82fcde
} __attribute__ ((packed));
Packit Service 82fcde
Packit Service 82fcde
static inline void *
Packit Service 82fcde
read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
read_1u (const void *p) { return *(const unsigned char *) p; }
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
read_1s (const void *p) { return *(const signed char *) p; }
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
Packit Service 82fcde
Packit Service 82fcde
static inline unsigned int
Packit Service 82fcde
read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
Packit Service 82fcde
Packit Service 82fcde
static inline unsigned long
Packit Service 82fcde
read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
Packit Service 82fcde
Packit Service 82fcde
static inline unsigned long
Packit Service 82fcde
read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
Packit Service 82fcde

Packit Service 82fcde
/* Get the value of register REG as saved in CONTEXT.  */
Packit Service 82fcde
Packit Service 82fcde
inline _Unwind_Word
Packit Service 82fcde
_Unwind_GetGR (struct _Unwind_Context *context, int index)
Packit Service 82fcde
{
Packit Service 82fcde
  /* This will segfault if the register hasn't been saved.  */
Packit Service 82fcde
  return * (_Unwind_Word *) context->reg[index];
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Get the value of the CFA as saved in CONTEXT.  */
Packit Service 82fcde
Packit Service 82fcde
_Unwind_Word
Packit Service 82fcde
_Unwind_GetCFA (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return (_Unwind_Ptr) context->cfa;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Overwrite the saved value for register REG in CONTEXT with VAL.  */
Packit Service 82fcde
Packit Service 82fcde
inline void
Packit Service 82fcde
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
Packit Service 82fcde
{
Packit Service 82fcde
  * (_Unwind_Word *) context->reg[index] = val;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Retrieve the return address for CONTEXT.  */
Packit Service 82fcde
Packit Service 82fcde
inline _Unwind_Ptr
Packit Service 82fcde
_Unwind_GetIP (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return (_Unwind_Ptr) context->ra;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Overwrite the return address for CONTEXT with VAL.  */
Packit Service 82fcde
Packit Service 82fcde
inline void
Packit Service 82fcde
_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
Packit Service 82fcde
{
Packit Service 82fcde
  context->ra = (void *) val;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void *
Packit Service 82fcde
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return context->lsda;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
_Unwind_Ptr
Packit Service 82fcde
_Unwind_GetRegionStart (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return (_Unwind_Ptr) context->bases.func;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void *
Packit Service 82fcde
_Unwind_FindEnclosingFunction (void *pc)
Packit Service 82fcde
{
Packit Service 82fcde
  struct dwarf_eh_bases bases;
Packit Service 82fcde
  struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
Packit Service 82fcde
  if (fde)
Packit Service 82fcde
    return bases.func;
Packit Service 82fcde
  else
Packit Service 82fcde
    return NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef __ia64__
Packit Service 82fcde
_Unwind_Ptr
Packit Service 82fcde
_Unwind_GetDataRelBase (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return (_Unwind_Ptr) context->bases.dbase;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
_Unwind_Ptr
Packit Service 82fcde
_Unwind_GetTextRelBase (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return (_Unwind_Ptr) context->bases.tbase;
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde

Packit Service 82fcde
/* Extract any interesting information from the CIE for the translation
Packit Service 82fcde
   unit F belongs to.  Return a pointer to the byte after the augmentation,
Packit Service 82fcde
   or NULL if we encountered an undecipherable augmentation.  */
Packit Service 82fcde
Packit Service 82fcde
static const unsigned char *
Packit Service 82fcde
extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
Packit Service 82fcde
		  _Unwind_FrameState *fs)
Packit Service 82fcde
{
Packit Service 82fcde
  const unsigned char *aug = cie->augmentation;
Packit Service 82fcde
  const unsigned char *p = aug + strlen ((const char *) aug) + 1;
Packit Service 82fcde
  const unsigned char *ret = NULL;
Packit Service 82fcde
  _Unwind_Word utmp;
Packit Service 82fcde
Packit Service 82fcde
  /* g++ v2 "eh" has pointer immediately following augmentation string,
Packit Service 82fcde
     so it must be handled first.  */
Packit Service 82fcde
  if (aug[0] == 'e' && aug[1] == 'h')
Packit Service 82fcde
    {
Packit Service 82fcde
      fs->eh_ptr = read_pointer (p);
Packit Service 82fcde
      p += sizeof (void *);
Packit Service 82fcde
      aug += 2;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Immediately following the augmentation are the code and
Packit Service 82fcde
     data alignment and return address column.  */
Packit Service 82fcde
  p = read_uleb128 (p, &fs->code_align);
Packit Service 82fcde
  p = read_sleb128 (p, &fs->data_align);
Packit Service 82fcde
  fs->retaddr_column = *p++;
Packit Service 82fcde
  fs->lsda_encoding = DW_EH_PE_omit;
Packit Service 82fcde
Packit Service 82fcde
  /* If the augmentation starts with 'z', then a uleb128 immediately
Packit Service 82fcde
     follows containing the length of the augmentation field following
Packit Service 82fcde
     the size.  */
Packit Service 82fcde
  if (*aug == 'z')
Packit Service 82fcde
    {
Packit Service 82fcde
      p = read_uleb128 (p, &utmp);
Packit Service 82fcde
      ret = p + utmp;
Packit Service 82fcde
Packit Service 82fcde
      fs->saw_z = 1;
Packit Service 82fcde
      ++aug;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Iterate over recognized augmentation subsequences.  */
Packit Service 82fcde
  while (*aug != '\0')
Packit Service 82fcde
    {
Packit Service 82fcde
      /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
Packit Service 82fcde
      if (aug[0] == 'L')
Packit Service 82fcde
	{
Packit Service 82fcde
	  fs->lsda_encoding = *p++;
Packit Service 82fcde
	  aug += 1;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* "R" indicates a byte indicating how FDE addresses are encoded.  */
Packit Service 82fcde
      else if (aug[0] == 'R')
Packit Service 82fcde
	{
Packit Service 82fcde
	  fs->fde_encoding = *p++;
Packit Service 82fcde
	  aug += 1;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* "P" indicates a personality routine in the CIE augmentation.  */
Packit Service 82fcde
      else if (aug[0] == 'P')
Packit Service 82fcde
	{
Packit Service 82fcde
	  _Unwind_Ptr personality;
Packit Service 82fcde
	  p = read_encoded_value (context, *p, p + 1, &personality);
Packit Service 82fcde
	  fs->personality = (_Unwind_Personality_Fn) personality;
Packit Service 82fcde
	  aug += 1;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Otherwise we have an unknown augmentation string.
Packit Service 82fcde
	 Bail unless we saw a 'z' prefix.  */
Packit Service 82fcde
      else
Packit Service 82fcde
	return ret;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return ret ? ret : p;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef _LIBC
Packit Service 82fcde
/* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
Packit Service 82fcde
   onto the stack to start.  */
Packit Service 82fcde
Packit Service 82fcde
static _Unwind_Word
Packit Service 82fcde
execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
Packit Service 82fcde
		  struct _Unwind_Context *context, _Unwind_Word initial)
Packit Service 82fcde
{
Packit Service 82fcde
  _Unwind_Word stack[64];	/* ??? Assume this is enough.  */
Packit Service 82fcde
  int stack_elt;
Packit Service 82fcde
Packit Service 82fcde
  stack[0] = initial;
Packit Service 82fcde
  stack_elt = 1;
Packit Service 82fcde
Packit Service 82fcde
  while (op_ptr < op_end)
Packit Service 82fcde
    {
Packit Service 82fcde
      enum dwarf_location_atom op = *op_ptr++;
Packit Service 82fcde
      _Unwind_Word result, reg, utmp;
Packit Service 82fcde
      _Unwind_Sword offset, stmp;
Packit Service 82fcde
Packit Service 82fcde
      switch (op)
Packit Service 82fcde
	{
Packit Service 82fcde
	case DW_OP_lit0:
Packit Service 82fcde
	case DW_OP_lit1:
Packit Service 82fcde
	case DW_OP_lit2:
Packit Service 82fcde
	case DW_OP_lit3:
Packit Service 82fcde
	case DW_OP_lit4:
Packit Service 82fcde
	case DW_OP_lit5:
Packit Service 82fcde
	case DW_OP_lit6:
Packit Service 82fcde
	case DW_OP_lit7:
Packit Service 82fcde
	case DW_OP_lit8:
Packit Service 82fcde
	case DW_OP_lit9:
Packit Service 82fcde
	case DW_OP_lit10:
Packit Service 82fcde
	case DW_OP_lit11:
Packit Service 82fcde
	case DW_OP_lit12:
Packit Service 82fcde
	case DW_OP_lit13:
Packit Service 82fcde
	case DW_OP_lit14:
Packit Service 82fcde
	case DW_OP_lit15:
Packit Service 82fcde
	case DW_OP_lit16:
Packit Service 82fcde
	case DW_OP_lit17:
Packit Service 82fcde
	case DW_OP_lit18:
Packit Service 82fcde
	case DW_OP_lit19:
Packit Service 82fcde
	case DW_OP_lit20:
Packit Service 82fcde
	case DW_OP_lit21:
Packit Service 82fcde
	case DW_OP_lit22:
Packit Service 82fcde
	case DW_OP_lit23:
Packit Service 82fcde
	case DW_OP_lit24:
Packit Service 82fcde
	case DW_OP_lit25:
Packit Service 82fcde
	case DW_OP_lit26:
Packit Service 82fcde
	case DW_OP_lit27:
Packit Service 82fcde
	case DW_OP_lit28:
Packit Service 82fcde
	case DW_OP_lit29:
Packit Service 82fcde
	case DW_OP_lit30:
Packit Service 82fcde
	case DW_OP_lit31:
Packit Service 82fcde
	  result = op - DW_OP_lit0;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_addr:
Packit Service 82fcde
	  result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
Packit Service 82fcde
	  op_ptr += sizeof (void *);
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_const1u:
Packit Service 82fcde
	  result = read_1u (op_ptr);
Packit Service 82fcde
	  op_ptr += 1;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const1s:
Packit Service 82fcde
	  result = read_1s (op_ptr);
Packit Service 82fcde
	  op_ptr += 1;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const2u:
Packit Service 82fcde
	  result = read_2u (op_ptr);
Packit Service 82fcde
	  op_ptr += 2;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const2s:
Packit Service 82fcde
	  result = read_2s (op_ptr);
Packit Service 82fcde
	  op_ptr += 2;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const4u:
Packit Service 82fcde
	  result = read_4u (op_ptr);
Packit Service 82fcde
	  op_ptr += 4;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const4s:
Packit Service 82fcde
	  result = read_4s (op_ptr);
Packit Service 82fcde
	  op_ptr += 4;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const8u:
Packit Service 82fcde
	  result = read_8u (op_ptr);
Packit Service 82fcde
	  op_ptr += 8;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_const8s:
Packit Service 82fcde
	  result = read_8s (op_ptr);
Packit Service 82fcde
	  op_ptr += 8;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_constu:
Packit Service 82fcde
	  op_ptr = read_uleb128 (op_ptr, &result);
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_consts:
Packit Service 82fcde
	  op_ptr = read_sleb128 (op_ptr, &stmp);
Packit Service 82fcde
	  result = stmp;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_reg0:
Packit Service 82fcde
	case DW_OP_reg1:
Packit Service 82fcde
	case DW_OP_reg2:
Packit Service 82fcde
	case DW_OP_reg3:
Packit Service 82fcde
	case DW_OP_reg4:
Packit Service 82fcde
	case DW_OP_reg5:
Packit Service 82fcde
	case DW_OP_reg6:
Packit Service 82fcde
	case DW_OP_reg7:
Packit Service 82fcde
	case DW_OP_reg8:
Packit Service 82fcde
	case DW_OP_reg9:
Packit Service 82fcde
	case DW_OP_reg10:
Packit Service 82fcde
	case DW_OP_reg11:
Packit Service 82fcde
	case DW_OP_reg12:
Packit Service 82fcde
	case DW_OP_reg13:
Packit Service 82fcde
	case DW_OP_reg14:
Packit Service 82fcde
	case DW_OP_reg15:
Packit Service 82fcde
	case DW_OP_reg16:
Packit Service 82fcde
	case DW_OP_reg17:
Packit Service 82fcde
	case DW_OP_reg18:
Packit Service 82fcde
	case DW_OP_reg19:
Packit Service 82fcde
	case DW_OP_reg20:
Packit Service 82fcde
	case DW_OP_reg21:
Packit Service 82fcde
	case DW_OP_reg22:
Packit Service 82fcde
	case DW_OP_reg23:
Packit Service 82fcde
	case DW_OP_reg24:
Packit Service 82fcde
	case DW_OP_reg25:
Packit Service 82fcde
	case DW_OP_reg26:
Packit Service 82fcde
	case DW_OP_reg27:
Packit Service 82fcde
	case DW_OP_reg28:
Packit Service 82fcde
	case DW_OP_reg29:
Packit Service 82fcde
	case DW_OP_reg30:
Packit Service 82fcde
	case DW_OP_reg31:
Packit Service 82fcde
	  result = _Unwind_GetGR (context, op - DW_OP_reg0);
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_regx:
Packit Service 82fcde
	  op_ptr = read_uleb128 (op_ptr, ®);
Packit Service 82fcde
	  result = _Unwind_GetGR (context, reg);
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_breg0:
Packit Service 82fcde
	case DW_OP_breg1:
Packit Service 82fcde
	case DW_OP_breg2:
Packit Service 82fcde
	case DW_OP_breg3:
Packit Service 82fcde
	case DW_OP_breg4:
Packit Service 82fcde
	case DW_OP_breg5:
Packit Service 82fcde
	case DW_OP_breg6:
Packit Service 82fcde
	case DW_OP_breg7:
Packit Service 82fcde
	case DW_OP_breg8:
Packit Service 82fcde
	case DW_OP_breg9:
Packit Service 82fcde
	case DW_OP_breg10:
Packit Service 82fcde
	case DW_OP_breg11:
Packit Service 82fcde
	case DW_OP_breg12:
Packit Service 82fcde
	case DW_OP_breg13:
Packit Service 82fcde
	case DW_OP_breg14:
Packit Service 82fcde
	case DW_OP_breg15:
Packit Service 82fcde
	case DW_OP_breg16:
Packit Service 82fcde
	case DW_OP_breg17:
Packit Service 82fcde
	case DW_OP_breg18:
Packit Service 82fcde
	case DW_OP_breg19:
Packit Service 82fcde
	case DW_OP_breg20:
Packit Service 82fcde
	case DW_OP_breg21:
Packit Service 82fcde
	case DW_OP_breg22:
Packit Service 82fcde
	case DW_OP_breg23:
Packit Service 82fcde
	case DW_OP_breg24:
Packit Service 82fcde
	case DW_OP_breg25:
Packit Service 82fcde
	case DW_OP_breg26:
Packit Service 82fcde
	case DW_OP_breg27:
Packit Service 82fcde
	case DW_OP_breg28:
Packit Service 82fcde
	case DW_OP_breg29:
Packit Service 82fcde
	case DW_OP_breg30:
Packit Service 82fcde
	case DW_OP_breg31:
Packit Service 82fcde
	  op_ptr = read_sleb128 (op_ptr, &offset);
Packit Service 82fcde
	  result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_OP_bregx:
Packit Service 82fcde
	  op_ptr = read_uleb128 (op_ptr, ®);
Packit Service 82fcde
	  op_ptr = read_sleb128 (op_ptr, &offset);
Packit Service 82fcde
	  result = _Unwind_GetGR (context, reg) + offset;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_dup:
Packit Service 82fcde
	  if (stack_elt < 1)
Packit Service 82fcde
	    abort ();
Packit Service 82fcde
	  result = stack[stack_elt - 1];
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_drop:
Packit Service 82fcde
	  if (--stack_elt < 0)
Packit Service 82fcde
	    abort ();
Packit Service 82fcde
	  goto no_push;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_pick:
Packit Service 82fcde
	  offset = *op_ptr++;
Packit Service 82fcde
	  if (offset >= stack_elt - 1)
Packit Service 82fcde
	    abort ();
Packit Service 82fcde
	  result = stack[stack_elt - 1 - offset];
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_over:
Packit Service 82fcde
	  if (stack_elt < 2)
Packit Service 82fcde
	    abort ();
Packit Service 82fcde
	  result = stack[stack_elt - 2];
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_rot:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    _Unwind_Word t1, t2, t3;
Packit Service 82fcde
Packit Service 82fcde
	    if (stack_elt < 3)
Packit Service 82fcde
	      abort ();
Packit Service 82fcde
	    t1 = stack[stack_elt - 1];
Packit Service 82fcde
	    t2 = stack[stack_elt - 2];
Packit Service 82fcde
	    t3 = stack[stack_elt - 3];
Packit Service 82fcde
	    stack[stack_elt - 1] = t2;
Packit Service 82fcde
	    stack[stack_elt - 2] = t3;
Packit Service 82fcde
	    stack[stack_elt - 3] = t1;
Packit Service 82fcde
	    goto no_push;
Packit Service 82fcde
	  }
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_deref:
Packit Service 82fcde
	case DW_OP_deref_size:
Packit Service 82fcde
	case DW_OP_abs:
Packit Service 82fcde
	case DW_OP_neg:
Packit Service 82fcde
	case DW_OP_not:
Packit Service 82fcde
	case DW_OP_plus_uconst:
Packit Service 82fcde
	  /* Unary operations.  */
Packit Service 82fcde
	  if (--stack_elt < 0)
Packit Service 82fcde
	    abort ();
Packit Service 82fcde
	  result = stack[stack_elt];
Packit Service 82fcde
Packit Service 82fcde
	  switch (op)
Packit Service 82fcde
	    {
Packit Service 82fcde
	    case DW_OP_deref:
Packit Service 82fcde
	      {
Packit Service 82fcde
		void *ptr = (void *) (_Unwind_Ptr) result;
Packit Service 82fcde
		result = (_Unwind_Ptr) read_pointer (ptr);
Packit Service 82fcde
	      }
Packit Service 82fcde
	      break;
Packit Service 82fcde
Packit Service 82fcde
	    case DW_OP_deref_size:
Packit Service 82fcde
	      {
Packit Service 82fcde
		void *ptr = (void *) (_Unwind_Ptr) result;
Packit Service 82fcde
		switch (*op_ptr++)
Packit Service 82fcde
		  {
Packit Service 82fcde
		  case 1:
Packit Service 82fcde
		    result = read_1u (ptr);
Packit Service 82fcde
		    break;
Packit Service 82fcde
		  case 2:
Packit Service 82fcde
		    result = read_2u (ptr);
Packit Service 82fcde
		    break;
Packit Service 82fcde
		  case 4:
Packit Service 82fcde
		    result = read_4u (ptr);
Packit Service 82fcde
		    break;
Packit Service 82fcde
		  case 8:
Packit Service 82fcde
		    result = read_8u (ptr);
Packit Service 82fcde
		    break;
Packit Service 82fcde
		  default:
Packit Service 82fcde
		    abort ();
Packit Service 82fcde
		  }
Packit Service 82fcde
	      }
Packit Service 82fcde
	      break;
Packit Service 82fcde
Packit Service 82fcde
	    case DW_OP_abs:
Packit Service 82fcde
	      if ((_Unwind_Sword) result < 0)
Packit Service 82fcde
		result = -result;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    case DW_OP_neg:
Packit Service 82fcde
	      result = -result;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    case DW_OP_not:
Packit Service 82fcde
	      result = ~result;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    case DW_OP_plus_uconst:
Packit Service 82fcde
	      op_ptr = read_uleb128 (op_ptr, &utmp);
Packit Service 82fcde
	      result += utmp;
Packit Service 82fcde
	      break;
Packit Service 82fcde
Packit Service 82fcde
	    default:
Packit Service 82fcde
	      abort ();
Packit Service 82fcde
	    }
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_and:
Packit Service 82fcde
	case DW_OP_div:
Packit Service 82fcde
	case DW_OP_minus:
Packit Service 82fcde
	case DW_OP_mod:
Packit Service 82fcde
	case DW_OP_mul:
Packit Service 82fcde
	case DW_OP_or:
Packit Service 82fcde
	case DW_OP_plus:
Packit Service 82fcde
	case DW_OP_le:
Packit Service 82fcde
	case DW_OP_ge:
Packit Service 82fcde
	case DW_OP_eq:
Packit Service 82fcde
	case DW_OP_lt:
Packit Service 82fcde
	case DW_OP_gt:
Packit Service 82fcde
	case DW_OP_ne:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    /* Binary operations.  */
Packit Service 82fcde
	    _Unwind_Word first, second;
Packit Service 82fcde
	    if ((stack_elt -= 2) < 0)
Packit Service 82fcde
	      abort ();
Packit Service 82fcde
	    second = stack[stack_elt];
Packit Service 82fcde
	    first = stack[stack_elt + 1];
Packit Service 82fcde
Packit Service 82fcde
	    switch (op)
Packit Service 82fcde
	      {
Packit Service 82fcde
	      case DW_OP_and:
Packit Service 82fcde
		result = second & first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_div:
Packit Service 82fcde
		result = (_Unwind_Sword) second / (_Unwind_Sword) first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_minus:
Packit Service 82fcde
		result = second - first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_mod:
Packit Service 82fcde
		result = (_Unwind_Sword) second % (_Unwind_Sword) first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_mul:
Packit Service 82fcde
		result = second * first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_or:
Packit Service 82fcde
		result = second | first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_plus:
Packit Service 82fcde
		result = second + first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_shl:
Packit Service 82fcde
		result = second << first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_shr:
Packit Service 82fcde
		result = second >> first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_shra:
Packit Service 82fcde
		result = (_Unwind_Sword) second >> first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_xor:
Packit Service 82fcde
		result = second ^ first;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_le:
Packit Service 82fcde
		result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_ge:
Packit Service 82fcde
		result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_eq:
Packit Service 82fcde
		result = (_Unwind_Sword) first == (_Unwind_Sword) second;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_lt:
Packit Service 82fcde
		result = (_Unwind_Sword) first < (_Unwind_Sword) second;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_gt:
Packit Service 82fcde
		result = (_Unwind_Sword) first > (_Unwind_Sword) second;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      case DW_OP_ne:
Packit Service 82fcde
		result = (_Unwind_Sword) first != (_Unwind_Sword) second;
Packit Service 82fcde
		break;
Packit Service 82fcde
Packit Service 82fcde
	      default:
Packit Service 82fcde
		abort ();
Packit Service 82fcde
	      }
Packit Service 82fcde
	  }
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_skip:
Packit Service 82fcde
	  offset = read_2s (op_ptr);
Packit Service 82fcde
	  op_ptr += 2;
Packit Service 82fcde
	  op_ptr += offset;
Packit Service 82fcde
	  goto no_push;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_bra:
Packit Service 82fcde
	  if (--stack_elt < 0)
Packit Service 82fcde
	    abort ();
Packit Service 82fcde
	  offset = read_2s (op_ptr);
Packit Service 82fcde
	  op_ptr += 2;
Packit Service 82fcde
	  if (stack[stack_elt] != 0)
Packit Service 82fcde
	    op_ptr += offset;
Packit Service 82fcde
	  goto no_push;
Packit Service 82fcde
Packit Service 82fcde
	case DW_OP_nop:
Packit Service 82fcde
	  goto no_push;
Packit Service 82fcde
Packit Service 82fcde
	default:
Packit Service 82fcde
	  abort ();
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Most things push a result value.  */
Packit Service 82fcde
      if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
Packit Service 82fcde
	abort ();
Packit Service 82fcde
      stack[stack_elt++] = result;
Packit Service 82fcde
    no_push:;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* We were executing this program to get a value.  It should be
Packit Service 82fcde
     at top of stack.  */
Packit Service 82fcde
  if (--stack_elt < 0)
Packit Service 82fcde
    abort ();
Packit Service 82fcde
  return stack[stack_elt];
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Decode DWARF 2 call frame information. Takes pointers the
Packit Service 82fcde
   instruction sequence to decode, current register information and
Packit Service 82fcde
   CIE info, and the PC range to evaluate.  */
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
execute_cfa_program (const unsigned char *insn_ptr,
Packit Service 82fcde
		     const unsigned char *insn_end,
Packit Service 82fcde
		     struct _Unwind_Context *context,
Packit Service 82fcde
		     _Unwind_FrameState *fs)
Packit Service 82fcde
{
Packit Service 82fcde
  struct frame_state_reg_info *unused_rs = NULL;
Packit Service 82fcde
Packit Service 82fcde
  /* Don't allow remember/restore between CIE and FDE programs.  */
Packit Service 82fcde
  fs->regs.prev = NULL;
Packit Service 82fcde
Packit Service 82fcde
  /* The comparison with the return address uses < rather than <= because
Packit Service 82fcde
     we are only interested in the effects of code before the call; for a
Packit Service 82fcde
     noreturn function, the return address may point to unrelated code with
Packit Service 82fcde
     a different stack configuration that we are not interested in.  We
Packit Service 82fcde
     assume that the call itself is unwind info-neutral; if not, or if
Packit Service 82fcde
     there are delay instructions that adjust the stack, these must be
Packit Service 82fcde
     reflected at the point immediately before the call insn.  */
Packit Service 82fcde
  while (insn_ptr < insn_end && fs->pc < context->ra)
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned char insn = *insn_ptr++;
Packit Service 82fcde
      _Unwind_Word reg, utmp;
Packit Service 82fcde
      _Unwind_Sword offset, stmp;
Packit Service 82fcde
Packit Service 82fcde
      if ((insn & 0xc0) == DW_CFA_advance_loc)
Packit Service 82fcde
	fs->pc += (insn & 0x3f) * fs->code_align;
Packit Service 82fcde
      else if ((insn & 0xc0) == DW_CFA_offset)
Packit Service 82fcde
	{
Packit Service 82fcde
	  reg = insn & 0x3f;
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  offset = (_Unwind_Sword) utmp * fs->data_align;
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
Packit Service 82fcde
	  fs->regs.reg[reg].loc.offset = offset;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if ((insn & 0xc0) == DW_CFA_restore)
Packit Service 82fcde
	{
Packit Service 82fcde
	  reg = insn & 0x3f;
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_UNSAVED;
Packit Service 82fcde
	}
Packit Service 82fcde
      else switch (insn)
Packit Service 82fcde
	{
Packit Service 82fcde
	case DW_CFA_set_loc:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    _Unwind_Ptr pc;
Packit Service 82fcde
	    insn_ptr = read_encoded_value (context, fs->fde_encoding,
Packit Service 82fcde
					   insn_ptr, &pc);
Packit Service 82fcde
	    fs->pc = (void *) pc;
Packit Service 82fcde
	  }
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_advance_loc1:
Packit Service 82fcde
	  fs->pc += read_1u (insn_ptr) * fs->code_align;
Packit Service 82fcde
	  insn_ptr += 1;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_CFA_advance_loc2:
Packit Service 82fcde
	  fs->pc += read_2u (insn_ptr) * fs->code_align;
Packit Service 82fcde
	  insn_ptr += 2;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case DW_CFA_advance_loc4:
Packit Service 82fcde
	  fs->pc += read_4u (insn_ptr) * fs->code_align;
Packit Service 82fcde
	  insn_ptr += 4;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_offset_extended:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  offset = (_Unwind_Sword) utmp * fs->data_align;
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
Packit Service 82fcde
	  fs->regs.reg[reg].loc.offset = offset;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_restore_extended:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_UNSAVED;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_undefined:
Packit Service 82fcde
	case DW_CFA_same_value:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_nop:
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_register:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    _Unwind_Word reg2;
Packit Service 82fcde
	    insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	    insn_ptr = read_uleb128 (insn_ptr, ®2;;
Packit Service 82fcde
	    fs->regs.reg[reg].how = REG_SAVED_REG;
Packit Service 82fcde
	    fs->regs.reg[reg].loc.reg = reg2;
Packit Service 82fcde
	  }
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_remember_state:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    struct frame_state_reg_info *new_rs;
Packit Service 82fcde
	    if (unused_rs)
Packit Service 82fcde
	      {
Packit Service 82fcde
		new_rs = unused_rs;
Packit Service 82fcde
		unused_rs = unused_rs->prev;
Packit Service 82fcde
	      }
Packit Service 82fcde
	    else
Packit Service 82fcde
	      new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
Packit Service 82fcde
Packit Service 82fcde
	    *new_rs = fs->regs;
Packit Service 82fcde
	    fs->regs.prev = new_rs;
Packit Service 82fcde
	  }
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_restore_state:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    struct frame_state_reg_info *old_rs = fs->regs.prev;
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
	    if (old_rs == NULL)
Packit Service 6615c7
	      __libc_fatal ("Invalid DWARF unwind data.\n");
Packit Service 82fcde
	    else
Packit Service 82fcde
#endif
Packit Service 82fcde
	      {
Packit Service 82fcde
		fs->regs = *old_rs;
Packit Service 82fcde
		old_rs->prev = unused_rs;
Packit Service 82fcde
		unused_rs = old_rs;
Packit Service 82fcde
	      }
Packit Service 82fcde
	  }
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_def_cfa:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  fs->cfa_offset = utmp;
Packit Service 82fcde
	  fs->cfa_how = CFA_REG_OFFSET;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_def_cfa_register:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
Packit Service 82fcde
	  fs->cfa_how = CFA_REG_OFFSET;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_def_cfa_offset:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  fs->cfa_offset = utmp;
Packit Service 82fcde
	  /* cfa_how deliberately not set.  */
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_def_cfa_expression:
Packit Service 82fcde
	  fs->cfa_exp = insn_ptr;
Packit Service 82fcde
	  fs->cfa_how = CFA_EXP;
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  insn_ptr += utmp;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_expression:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_SAVED_EXP;
Packit Service 82fcde
	  fs->regs.reg[reg].loc.exp = insn_ptr;
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  insn_ptr += utmp;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	  /* From the 2.1 draft.  */
Packit Service 82fcde
	case DW_CFA_offset_extended_sf:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
Packit Service 82fcde
	  offset = stmp * fs->data_align;
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
Packit Service 82fcde
	  fs->regs.reg[reg].loc.offset = offset;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_def_cfa_sf:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
Packit Service 82fcde
	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
Packit Service 82fcde
	  fs->cfa_how = CFA_REG_OFFSET;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_def_cfa_offset_sf:
Packit Service 82fcde
	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
Packit Service 82fcde
	  /* cfa_how deliberately not set.  */
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_GNU_window_save:
Packit Service 82fcde
	  /* ??? Hardcoded for SPARC register window configuration.
Packit Service 82fcde
	     At least do not do anything for archs which explicitly
Packit Service 82fcde
	     define a lower register number.  */
Packit Service 82fcde
#if DWARF_FRAME_REGISTERS >= 32
Packit Service 82fcde
	  for (reg = 16; reg < 32; ++reg)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
Packit Service 82fcde
	      fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
Packit Service 82fcde
	    }
Packit Service 82fcde
#endif
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_GNU_args_size:
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case DW_CFA_GNU_negative_offset_extended:
Packit Service 82fcde
	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
Packit Service 82fcde
	     older PowerPC code.  */
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Packit Service 82fcde
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
Packit Service 82fcde
	  offset = (_Unwind_Word) utmp * fs->data_align;
Packit Service 82fcde
	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
Packit Service 82fcde
	  fs->regs.reg[reg].loc.offset = -offset;
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	default:
Packit Service 82fcde
	  abort ();
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde

Packit Service 82fcde
/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
Packit Service 82fcde
   its caller and decode it into FS.  This function also sets the
Packit Service 82fcde
   args_size and lsda members of CONTEXT, as they are really information
Packit Service 82fcde
   about the caller's frame.  */
Packit Service 82fcde
Packit Service 82fcde
static _Unwind_Reason_Code
Packit Service 82fcde
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
Packit Service 82fcde
{
Packit Service 82fcde
  struct dwarf_fde *fde;
Packit Service 82fcde
  struct dwarf_cie *cie;
Packit Service 82fcde
  const unsigned char *aug, *insn, *end;
Packit Service 82fcde
Packit Service 82fcde
  memset (fs, 0, sizeof (*fs));
Packit Service 82fcde
  context->args_size = 0;
Packit Service 82fcde
  context->lsda = 0;
Packit Service 82fcde
Packit Service 82fcde
  fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
Packit Service 82fcde
  if (fde == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Couldn't find frame unwind info for this function.  Try a
Packit Service 82fcde
	 target-specific fallback mechanism.  This will necessarily
Packit Service 82fcde
	 not provide a personality routine or LSDA.  */
Packit Service 82fcde
#ifdef MD_FALLBACK_FRAME_STATE_FOR
Packit Service 82fcde
      MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
Packit Service 82fcde
      return _URC_END_OF_STACK;
Packit Service 82fcde
    success:
Packit Service 82fcde
      return _URC_NO_REASON;
Packit Service 82fcde
#else
Packit Service 82fcde
      return _URC_END_OF_STACK;
Packit Service 82fcde
#endif
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  fs->pc = context->bases.func;
Packit Service 82fcde
Packit Service 82fcde
  cie = get_cie (fde);
Packit Service 82fcde
  insn = extract_cie_info (cie, context, fs);
Packit Service 82fcde
  if (insn == NULL)
Packit Service 82fcde
    /* CIE contained unknown augmentation.  */
Packit Service 82fcde
    return _URC_FATAL_PHASE1_ERROR;
Packit Service 82fcde
Packit Service 82fcde
  /* First decode all the insns in the CIE.  */
Packit Service 82fcde
  end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
Packit Service 82fcde
  execute_cfa_program (insn, end, context, fs);
Packit Service 82fcde
Packit Service 82fcde
  /* Locate augmentation for the fde.  */
Packit Service 82fcde
  aug = (unsigned char *) fde + sizeof (*fde);
Packit Service 82fcde
  aug += 2 * size_of_encoded_value (fs->fde_encoding);
Packit Service 82fcde
  insn = NULL;
Packit Service 82fcde
  if (fs->saw_z)
Packit Service 82fcde
    {
Packit Service 82fcde
      _Unwind_Word i;
Packit Service 82fcde
      aug = read_uleb128 (aug, &i);
Packit Service 82fcde
      insn = aug + i;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (fs->lsda_encoding != DW_EH_PE_omit)
Packit Service 82fcde
    {
Packit Service 82fcde
      _Unwind_Ptr lsda;
Packit Service 82fcde
      aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
Packit Service 82fcde
      context->lsda = (void *) lsda;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Then the insns in the FDE up to our target PC.  */
Packit Service 82fcde
  if (insn == NULL)
Packit Service 82fcde
    insn = aug;
Packit Service 82fcde
  end = (unsigned char *) next_fde (fde);
Packit Service 82fcde
  execute_cfa_program (insn, end, context, fs);
Packit Service 82fcde
Packit Service 82fcde
  return _URC_NO_REASON;
Packit Service 82fcde
}
Packit Service 82fcde

Packit Service 82fcde
typedef struct frame_state
Packit Service 82fcde
{
Packit Service 82fcde
  void *cfa;
Packit Service 82fcde
  void *eh_ptr;
Packit Service 82fcde
  long cfa_offset;
Packit Service 82fcde
  long args_size;
Packit Service 82fcde
  long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
Packit Service 82fcde
  unsigned short cfa_reg;
Packit Service 82fcde
  unsigned short retaddr_column;
Packit Service 82fcde
  char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
Packit Service 82fcde
} frame_state;
Packit Service 82fcde
Packit Service 82fcde
#ifndef STATIC
Packit Service 82fcde
# define STATIC
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
STATIC
Packit Service 82fcde
struct frame_state * __frame_state_for (void *, struct frame_state *);
Packit Service 82fcde
Packit Service 82fcde
/* Called from pre-G++ 3.0 __throw to find the registers to restore for
Packit Service 82fcde
   a given PC_TARGET.  The caller should allocate a local variable of
Packit Service 82fcde
   `struct frame_state' and pass its address to STATE_IN.  */
Packit Service 82fcde
Packit Service 82fcde
STATIC
Packit Service 82fcde
struct frame_state *
Packit Service 82fcde
__frame_state_for (void *pc_target, struct frame_state *state_in)
Packit Service 82fcde
{
Packit Service 82fcde
  struct _Unwind_Context context;
Packit Service 82fcde
  _Unwind_FrameState fs;
Packit Service 82fcde
  int reg;
Packit Service 82fcde
Packit Service 82fcde
  memset (&context, 0, sizeof (struct _Unwind_Context));
Packit Service 82fcde
  context.ra = pc_target + 1;
Packit Service 82fcde
Packit Service 82fcde
  if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
Packit Service 82fcde
    return 0;
Packit Service 82fcde
Packit Service 82fcde
  /* We have no way to pass a location expression for the CFA to our
Packit Service 82fcde
     caller.  It wouldn't understand it anyway.  */
Packit Service 82fcde
  if (fs.cfa_how == CFA_EXP)
Packit Service 82fcde
    return 0;
Packit Service 82fcde
Packit Service 82fcde
  for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
Packit Service 82fcde
    {
Packit Service 82fcde
      state_in->saved[reg] = fs.regs.reg[reg].how;
Packit Service 82fcde
      switch (state_in->saved[reg])
Packit Service 82fcde
	{
Packit Service 82fcde
	case REG_SAVED_REG:
Packit Service 82fcde
	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case REG_SAVED_OFFSET:
Packit Service 82fcde
	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	default:
Packit Service 82fcde
	  state_in->reg_or_offset[reg] = 0;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  state_in->cfa_offset = fs.cfa_offset;
Packit Service 82fcde
  state_in->cfa_reg = fs.cfa_reg;
Packit Service 82fcde
  state_in->retaddr_column = fs.retaddr_column;
Packit Service 82fcde
  state_in->args_size = context.args_size;
Packit Service 82fcde
  state_in->eh_ptr = fs.eh_ptr;
Packit Service 82fcde
Packit Service 82fcde
  return state_in;
Packit Service 82fcde
}
Packit Service 82fcde

Packit Service 82fcde
#ifndef _LIBC
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
Packit Service 82fcde
{
Packit Service 82fcde
  struct _Unwind_Context orig_context = *context;
Packit Service 82fcde
  void *cfa;
Packit Service 82fcde
  long i;
Packit Service 82fcde
Packit Service 82fcde
#ifdef EH_RETURN_STACKADJ_RTX
Packit Service 82fcde
  /* Special handling here: Many machines do not use a frame pointer,
Packit Service 82fcde
     and track the CFA only through offsets from the stack pointer from
Packit Service 82fcde
     one frame to the next.  In this case, the stack pointer is never
Packit Service 82fcde
     stored, so it has no saved address in the context.  What we do
Packit Service 82fcde
     have is the CFA from the previous stack frame.
Packit Service 82fcde
Packit Service 82fcde
     In very special situations (such as unwind info for signal return),
Packit Service 82fcde
     there may be location expressions that use the stack pointer as well.
Packit Service 82fcde
Packit Service 82fcde
     Do this conditionally for one frame.  This allows the unwind info
Packit Service 82fcde
     for one frame to save a copy of the stack pointer from the previous
Packit Service 82fcde
     frame, and be able to use much easier CFA mechanisms to do it.
Packit Service 82fcde
     Always zap the saved stack pointer value for the next frame; carrying
Packit Service 82fcde
     the value over from one frame to another doesn't make sense.  */
Packit Service 82fcde
Packit Service 82fcde
  _Unwind_Word tmp_sp;
Packit Service 82fcde
Packit Service 82fcde
  if (!orig_context.reg[__builtin_dwarf_sp_column ()])
Packit Service 82fcde
    {
Packit Service 82fcde
      tmp_sp = (_Unwind_Ptr) context->cfa;
Packit Service 82fcde
      orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
Packit Service 82fcde
    }
Packit Service 82fcde
  context->reg[__builtin_dwarf_sp_column ()] = NULL;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Compute this frame's CFA.  */
Packit Service 82fcde
  switch (fs->cfa_how)
Packit Service 82fcde
    {
Packit Service 82fcde
    case CFA_REG_OFFSET:
Packit Service 82fcde
      cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
Packit Service 82fcde
      cfa += fs->cfa_offset;
Packit Service 82fcde
      break;
Packit Service 82fcde
Packit Service 82fcde
    case CFA_EXP:
Packit Service 82fcde
      {
Packit Service 82fcde
	const unsigned char *exp = fs->cfa_exp;
Packit Service 82fcde
	_Unwind_Word len;
Packit Service 82fcde
Packit Service 82fcde
	exp = read_uleb128 (exp, &len;;
Packit Service 82fcde
	cfa = (void *) (_Unwind_Ptr)
Packit Service 82fcde
	  execute_stack_op (exp, exp + len, &orig_context, 0);
Packit Service 82fcde
	break;
Packit Service 82fcde
      }
Packit Service 82fcde
Packit Service 82fcde
    default:
Packit Service 82fcde
      abort ();
Packit Service 82fcde
    }
Packit Service 82fcde
  context->cfa = cfa;
Packit Service 82fcde
Packit Service 82fcde
  /* Compute the addresses of all registers saved in this frame.  */
Packit Service 82fcde
  for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
Packit Service 82fcde
    switch (fs->regs.reg[i].how)
Packit Service 82fcde
      {
Packit Service 82fcde
      case REG_UNSAVED:
Packit Service 82fcde
	break;
Packit Service 82fcde
Packit Service 82fcde
      case REG_SAVED_OFFSET:
Packit Service 82fcde
	context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
Packit Service 82fcde
	break;
Packit Service 82fcde
Packit Service 82fcde
      case REG_SAVED_REG:
Packit Service 82fcde
	context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
Packit Service 82fcde
	break;
Packit Service 82fcde
Packit Service 82fcde
      case REG_SAVED_EXP:
Packit Service 82fcde
	{
Packit Service 82fcde
	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
Packit Service 82fcde
	  _Unwind_Word len;
Packit Service 82fcde
	  _Unwind_Ptr val;
Packit Service 82fcde
Packit Service 82fcde
	  exp = read_uleb128 (exp, &len;;
Packit Service 82fcde
	  val = execute_stack_op (exp, exp + len, &orig_context,
Packit Service 82fcde
				  (_Unwind_Ptr) cfa);
Packit Service 82fcde
	  context->reg[i] = (void *) val;
Packit Service 82fcde
	}
Packit Service 82fcde
	break;
Packit Service 82fcde
      }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
Packit Service 82fcde
   of its caller.  Update CONTEXT to refer to the caller as well.  Note
Packit Service 82fcde
   that the args_size and lsda members are not updated here, but later in
Packit Service 82fcde
   uw_frame_state_for.  */
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
Packit Service 82fcde
{
Packit Service 82fcde
  uw_update_context_1 (context, fs);
Packit Service 82fcde
Packit Service 82fcde
  /* Compute the return address now, since the return address column
Packit Service 82fcde
     can change from frame to frame.  */
Packit Service 82fcde
  context->ra = __builtin_extract_return_addr
Packit Service 82fcde
    ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
Packit Service 82fcde
}
Packit Service 82fcde

Packit Service 82fcde
/* Fill in CONTEXT for top-of-stack.  The only valid registers at this
Packit Service 82fcde
   level will be the return address and the CFA.  */
Packit Service 82fcde
Packit Service 82fcde
#define uw_init_context(CONTEXT)					   \
Packit Service 82fcde
  do									   \
Packit Service 82fcde
    {									   \
Packit Service 82fcde
      /* Do any necessary initialization to access arbitrary stack frames. \
Packit Service 82fcde
	 On the SPARC, this means flushing the register windows.  */	   \
Packit Service 82fcde
      __builtin_unwind_init ();						   \
Packit Service 82fcde
      uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),		   \
Packit Service 82fcde
			 __builtin_return_address (0));			   \
Packit Service 82fcde
    }									   \
Packit Service 82fcde
  while (0)
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
uw_init_context_1 (struct _Unwind_Context *context,
Packit Service 82fcde
		   void *outer_cfa, void *outer_ra)
Packit Service 82fcde
{
Packit Service 82fcde
  void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
Packit Service 82fcde
  _Unwind_FrameState fs;
Packit Service 82fcde
  _Unwind_Word sp_slot;
Packit Service 82fcde
Packit Service 82fcde
  memset (context, 0, sizeof (struct _Unwind_Context));
Packit Service 82fcde
  context->ra = ra;
Packit Service 82fcde
Packit Service 82fcde
  if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
Packit Service 82fcde
    abort ();
Packit Service 82fcde
Packit Service 82fcde
  /* Force the frame state to use the known cfa value.  */
Packit Service 82fcde
  sp_slot = (_Unwind_Ptr) outer_cfa;
Packit Service 82fcde
  context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
Packit Service 82fcde
  fs.cfa_how = CFA_REG_OFFSET;
Packit Service 82fcde
  fs.cfa_reg = __builtin_dwarf_sp_column ();
Packit Service 82fcde
  fs.cfa_offset = 0;
Packit Service 82fcde
Packit Service 82fcde
  uw_update_context_1 (context, &fs);
Packit Service 82fcde
Packit Service 82fcde
  /* If the return address column was saved in a register in the
Packit Service 82fcde
     initialization context, then we can't see it in the given
Packit Service 82fcde
     call frame data.  So have the initialization context tell us.  */
Packit Service 82fcde
  context->ra = __builtin_extract_return_addr (outer_ra);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Install TARGET into CURRENT so that we can return to it.  This is a
Packit Service 82fcde
   macro because __builtin_eh_return must be invoked in the context of
Packit Service 82fcde
   our caller.  */
Packit Service 82fcde
Packit Service 82fcde
#define uw_install_context(CURRENT, TARGET)				 \
Packit Service 82fcde
  do									 \
Packit Service 82fcde
    {									 \
Packit Service 82fcde
      long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
Packit Service 82fcde
      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
Packit Service 82fcde
      __builtin_eh_return (offset, handler);				 \
Packit Service 82fcde
    }									 \
Packit Service 82fcde
  while (0)
Packit Service 82fcde
Packit Service 82fcde
static inline void
Packit Service 82fcde
init_dwarf_reg_size_table (void)
Packit Service 82fcde
{
Packit Service 82fcde
  __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static long
Packit Service 82fcde
uw_install_context_1 (struct _Unwind_Context *current,
Packit Service 82fcde
		      struct _Unwind_Context *target)
Packit Service 82fcde
{
Packit Service 82fcde
  long i;
Packit Service 82fcde
Packit Service 82fcde
#if __GTHREADS
Packit Service 82fcde
  {
Packit Service 82fcde
    static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
Packit Service 82fcde
    if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
Packit Service 82fcde
	|| dwarf_reg_size_table[0] == 0)
Packit Service 82fcde
      init_dwarf_reg_size_table ();
Packit Service 82fcde
  }
Packit Service 82fcde
#else
Packit Service 82fcde
  if (dwarf_reg_size_table[0] == 0)
Packit Service 82fcde
    init_dwarf_reg_size_table ();
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      void *c = current->reg[i];
Packit Service 82fcde
      void *t = target->reg[i];
Packit Service 82fcde
      if (t && c && t != c)
Packit Service 82fcde
	memcpy (c, t, dwarf_reg_size_table[i]);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#ifdef EH_RETURN_STACKADJ_RTX
Packit Service 82fcde
  {
Packit Service 82fcde
    void *target_cfa;
Packit Service 82fcde
Packit Service 82fcde
    /* If the last frame records a saved stack pointer, use it.  */
Packit Service 82fcde
    if (target->reg[__builtin_dwarf_sp_column ()])
Packit Service 82fcde
      target_cfa = (void *)(_Unwind_Ptr)
Packit Service 82fcde
        _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
Packit Service 82fcde
    else
Packit Service 82fcde
      target_cfa = target->cfa;
Packit Service 82fcde
Packit Service 82fcde
    /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
Packit Service 82fcde
    if (STACK_GROWS_DOWNWARD)
Packit Service 82fcde
      return target_cfa - current->cfa + target->args_size;
Packit Service 82fcde
    else
Packit Service 82fcde
      return current->cfa - target_cfa - target->args_size;
Packit Service 82fcde
  }
Packit Service 82fcde
#else
Packit Service 82fcde
  return 0;
Packit Service 82fcde
#endif
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static inline _Unwind_Ptr
Packit Service 82fcde
uw_identify_context (struct _Unwind_Context *context)
Packit Service 82fcde
{
Packit Service 82fcde
  return _Unwind_GetIP (context);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#include "unwind.inc"
Packit Service 82fcde
Packit Service 82fcde
#endif /* _LIBC */