Back to index

glibc  2.9
unwind-dw2.c
Go to the documentation of this file.
00001 /* DWARF2 exception handling and frame unwind runtime interface routines.
00002    Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006,2007
00003        Free Software Foundation, Inc.
00004 
00005    This file is part of the GNU C Library.
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    The GNU C Library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with the GNU C Library; if not, write to the Free
00019    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00020    02111-1307 USA.  */
00021 
00022 #ifdef _LIBC
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <error.h>
00026 #include <libintl.h>
00027 #include <dwarf2.h>
00028 #include <stdio.h>
00029 #include <unwind.h>
00030 #include <unwind-pe.h>
00031 #include <unwind-dw2-fde.h>
00032 #else
00033 #include "tconfig.h"
00034 #include "tsystem.h"
00035 #include "dwarf2.h"
00036 #include "unwind.h"
00037 #include "unwind-pe.h"
00038 #include "unwind-dw2-fde.h"
00039 #include "gthr.h"
00040 #endif
00041 
00042 
00043 
00044 #ifndef STACK_GROWS_DOWNWARD
00045 #define STACK_GROWS_DOWNWARD 0
00046 #else
00047 #undef STACK_GROWS_DOWNWARD
00048 #define STACK_GROWS_DOWNWARD 1
00049 #endif
00050 
00051 /* A target can override (perhaps for backward compatibility) how
00052    many dwarf2 columns are unwound.  */
00053 #ifndef DWARF_FRAME_REGISTERS
00054 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
00055 #endif
00056 
00057 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
00058 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
00059 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
00060 #endif
00061 
00062 /* This is the register and unwind state for a particular frame.  This
00063    provides the information necessary to unwind up past a frame and return
00064    to its caller.  */
00065 struct _Unwind_Context
00066 {
00067   void *reg[DWARF_FRAME_REGISTERS+1];
00068   void *cfa;
00069   void *ra;
00070   void *lsda;
00071   struct dwarf_eh_bases bases;
00072   _Unwind_Word args_size;
00073 };
00074 
00075 #ifndef _LIBC
00076 /* Byte size of every register managed by these routines.  */
00077 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
00078 #endif
00079 
00080 
00081 /* The result of interpreting the frame unwind info for a frame.
00082    This is all symbolic at this point, as none of the values can
00083    be resolved until the target pc is located.  */
00084 typedef struct
00085 {
00086   /* Each register save state can be described in terms of a CFA slot,
00087      another register, or a location expression.  */
00088   struct frame_state_reg_info
00089   {
00090     struct {
00091       union {
00092        _Unwind_Word reg;
00093        _Unwind_Sword offset;
00094        const unsigned char *exp;
00095       } loc;
00096       enum {
00097        REG_UNSAVED,
00098        REG_SAVED_OFFSET,
00099        REG_SAVED_REG,
00100        REG_SAVED_EXP,
00101       } how;
00102     } reg[DWARF_FRAME_REGISTERS+1];
00103 
00104     /* Used to implement DW_CFA_remember_state.  */
00105     struct frame_state_reg_info *prev;
00106   } regs;
00107 
00108   /* The CFA can be described in terms of a reg+offset or a
00109      location expression.  */
00110   _Unwind_Sword cfa_offset;
00111   _Unwind_Word cfa_reg;
00112   const unsigned char *cfa_exp;
00113   enum {
00114     CFA_UNSET,
00115     CFA_REG_OFFSET,
00116     CFA_EXP,
00117   } cfa_how;
00118 
00119   /* The PC described by the current frame state.  */
00120   void *pc;
00121 
00122   /* The information we care about from the CIE/FDE.  */
00123   _Unwind_Personality_Fn personality;
00124   _Unwind_Sword data_align;
00125   _Unwind_Word code_align;
00126   unsigned char retaddr_column;
00127   unsigned char fde_encoding;
00128   unsigned char lsda_encoding;
00129   unsigned char saw_z;
00130   void *eh_ptr;
00131 } _Unwind_FrameState;
00132 
00133 /* Read unaligned data from the instruction buffer.  */
00134 
00135 union unaligned
00136 {
00137   void *p;
00138   unsigned u2 __attribute__ ((mode (HI)));
00139   unsigned u4 __attribute__ ((mode (SI)));
00140   unsigned u8 __attribute__ ((mode (DI)));
00141   signed s2 __attribute__ ((mode (HI)));
00142   signed s4 __attribute__ ((mode (SI)));
00143   signed s8 __attribute__ ((mode (DI)));
00144 } __attribute__ ((packed));
00145 
00146 static inline void *
00147 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
00148 
00149 static inline int
00150 read_1u (const void *p) { return *(const unsigned char *) p; }
00151 
00152 static inline int
00153 read_1s (const void *p) { return *(const signed char *) p; }
00154 
00155 static inline int
00156 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
00157 
00158 static inline int
00159 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
00160 
00161 static inline unsigned int
00162 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
00163 
00164 static inline int
00165 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
00166 
00167 static inline unsigned long
00168 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
00169 
00170 static inline unsigned long
00171 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
00172 
00173 /* Get the value of register REG as saved in CONTEXT.  */
00174 
00175 inline _Unwind_Word
00176 _Unwind_GetGR (struct _Unwind_Context *context, int index)
00177 {
00178   /* This will segfault if the register hasn't been saved.  */
00179   return * (_Unwind_Word *) context->reg[index];
00180 }
00181 
00182 /* Get the value of the CFA as saved in CONTEXT.  */
00183 
00184 _Unwind_Word
00185 _Unwind_GetCFA (struct _Unwind_Context *context)
00186 {
00187   return (_Unwind_Ptr) context->cfa;
00188 }
00189 
00190 /* Overwrite the saved value for register REG in CONTEXT with VAL.  */
00191 
00192 inline void
00193 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
00194 {
00195   * (_Unwind_Word *) context->reg[index] = val;
00196 }
00197 
00198 /* Retrieve the return address for CONTEXT.  */
00199 
00200 inline _Unwind_Ptr
00201 _Unwind_GetIP (struct _Unwind_Context *context)
00202 {
00203   return (_Unwind_Ptr) context->ra;
00204 }
00205 
00206 /* Overwrite the return address for CONTEXT with VAL.  */
00207 
00208 inline void
00209 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
00210 {
00211   context->ra = (void *) val;
00212 }
00213 
00214 void *
00215 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
00216 {
00217   return context->lsda;
00218 }
00219 
00220 _Unwind_Ptr
00221 _Unwind_GetRegionStart (struct _Unwind_Context *context)
00222 {
00223   return (_Unwind_Ptr) context->bases.func;
00224 }
00225 
00226 void *
00227 _Unwind_FindEnclosingFunction (void *pc)
00228 {
00229   struct dwarf_eh_bases bases;
00230   struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
00231   if (fde)
00232     return bases.func;
00233   else
00234     return NULL;
00235 }
00236 
00237 #ifndef __ia64__
00238 _Unwind_Ptr
00239 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
00240 {
00241   return (_Unwind_Ptr) context->bases.dbase;
00242 }
00243 
00244 _Unwind_Ptr
00245 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
00246 {
00247   return (_Unwind_Ptr) context->bases.tbase;
00248 }
00249 #endif
00250 
00251 /* Extract any interesting information from the CIE for the translation
00252    unit F belongs to.  Return a pointer to the byte after the augmentation,
00253    or NULL if we encountered an undecipherable augmentation.  */
00254 
00255 static const unsigned char *
00256 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
00257                 _Unwind_FrameState *fs)
00258 {
00259   const unsigned char *aug = cie->augmentation;
00260   const unsigned char *p = aug + strlen ((const char *) aug) + 1;
00261   const unsigned char *ret = NULL;
00262   _Unwind_Word utmp;
00263 
00264   /* g++ v2 "eh" has pointer immediately following augmentation string,
00265      so it must be handled first.  */
00266   if (aug[0] == 'e' && aug[1] == 'h')
00267     {
00268       fs->eh_ptr = read_pointer (p);
00269       p += sizeof (void *);
00270       aug += 2;
00271     }
00272 
00273   /* Immediately following the augmentation are the code and
00274      data alignment and return address column.  */
00275   p = read_uleb128 (p, &fs->code_align);
00276   p = read_sleb128 (p, &fs->data_align);
00277   fs->retaddr_column = *p++;
00278   fs->lsda_encoding = DW_EH_PE_omit;
00279 
00280   /* If the augmentation starts with 'z', then a uleb128 immediately
00281      follows containing the length of the augmentation field following
00282      the size.  */
00283   if (*aug == 'z')
00284     {
00285       p = read_uleb128 (p, &utmp);
00286       ret = p + utmp;
00287 
00288       fs->saw_z = 1;
00289       ++aug;
00290     }
00291 
00292   /* Iterate over recognized augmentation subsequences.  */
00293   while (*aug != '\0')
00294     {
00295       /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
00296       if (aug[0] == 'L')
00297        {
00298          fs->lsda_encoding = *p++;
00299          aug += 1;
00300        }
00301 
00302       /* "R" indicates a byte indicating how FDE addresses are encoded.  */
00303       else if (aug[0] == 'R')
00304        {
00305          fs->fde_encoding = *p++;
00306          aug += 1;
00307        }
00308 
00309       /* "P" indicates a personality routine in the CIE augmentation.  */
00310       else if (aug[0] == 'P')
00311        {
00312          _Unwind_Ptr personality;
00313          p = read_encoded_value (context, *p, p + 1, &personality);
00314          fs->personality = (_Unwind_Personality_Fn) personality;
00315          aug += 1;
00316        }
00317 
00318       /* Otherwise we have an unknown augmentation string.
00319         Bail unless we saw a 'z' prefix.  */
00320       else
00321        return ret;
00322     }
00323 
00324   return ret ? ret : p;
00325 }
00326 
00327 #ifndef _LIBC
00328 /* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
00329    onto the stack to start.  */
00330 
00331 static _Unwind_Word
00332 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
00333                 struct _Unwind_Context *context, _Unwind_Word initial)
00334 {
00335   _Unwind_Word stack[64];   /* ??? Assume this is enough.  */
00336   int stack_elt;
00337 
00338   stack[0] = initial;
00339   stack_elt = 1;
00340 
00341   while (op_ptr < op_end)
00342     {
00343       enum dwarf_location_atom op = *op_ptr++;
00344       _Unwind_Word result, reg, utmp;
00345       _Unwind_Sword offset, stmp;
00346 
00347       switch (op)
00348        {
00349        case DW_OP_lit0:
00350        case DW_OP_lit1:
00351        case DW_OP_lit2:
00352        case DW_OP_lit3:
00353        case DW_OP_lit4:
00354        case DW_OP_lit5:
00355        case DW_OP_lit6:
00356        case DW_OP_lit7:
00357        case DW_OP_lit8:
00358        case DW_OP_lit9:
00359        case DW_OP_lit10:
00360        case DW_OP_lit11:
00361        case DW_OP_lit12:
00362        case DW_OP_lit13:
00363        case DW_OP_lit14:
00364        case DW_OP_lit15:
00365        case DW_OP_lit16:
00366        case DW_OP_lit17:
00367        case DW_OP_lit18:
00368        case DW_OP_lit19:
00369        case DW_OP_lit20:
00370        case DW_OP_lit21:
00371        case DW_OP_lit22:
00372        case DW_OP_lit23:
00373        case DW_OP_lit24:
00374        case DW_OP_lit25:
00375        case DW_OP_lit26:
00376        case DW_OP_lit27:
00377        case DW_OP_lit28:
00378        case DW_OP_lit29:
00379        case DW_OP_lit30:
00380        case DW_OP_lit31:
00381          result = op - DW_OP_lit0;
00382          break;
00383 
00384        case DW_OP_addr:
00385          result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
00386          op_ptr += sizeof (void *);
00387          break;
00388 
00389        case DW_OP_const1u:
00390          result = read_1u (op_ptr);
00391          op_ptr += 1;
00392          break;
00393        case DW_OP_const1s:
00394          result = read_1s (op_ptr);
00395          op_ptr += 1;
00396          break;
00397        case DW_OP_const2u:
00398          result = read_2u (op_ptr);
00399          op_ptr += 2;
00400          break;
00401        case DW_OP_const2s:
00402          result = read_2s (op_ptr);
00403          op_ptr += 2;
00404          break;
00405        case DW_OP_const4u:
00406          result = read_4u (op_ptr);
00407          op_ptr += 4;
00408          break;
00409        case DW_OP_const4s:
00410          result = read_4s (op_ptr);
00411          op_ptr += 4;
00412          break;
00413        case DW_OP_const8u:
00414          result = read_8u (op_ptr);
00415          op_ptr += 8;
00416          break;
00417        case DW_OP_const8s:
00418          result = read_8s (op_ptr);
00419          op_ptr += 8;
00420          break;
00421        case DW_OP_constu:
00422          op_ptr = read_uleb128 (op_ptr, &result);
00423          break;
00424        case DW_OP_consts:
00425          op_ptr = read_sleb128 (op_ptr, &stmp);
00426          result = stmp;
00427          break;
00428 
00429        case DW_OP_reg0:
00430        case DW_OP_reg1:
00431        case DW_OP_reg2:
00432        case DW_OP_reg3:
00433        case DW_OP_reg4:
00434        case DW_OP_reg5:
00435        case DW_OP_reg6:
00436        case DW_OP_reg7:
00437        case DW_OP_reg8:
00438        case DW_OP_reg9:
00439        case DW_OP_reg10:
00440        case DW_OP_reg11:
00441        case DW_OP_reg12:
00442        case DW_OP_reg13:
00443        case DW_OP_reg14:
00444        case DW_OP_reg15:
00445        case DW_OP_reg16:
00446        case DW_OP_reg17:
00447        case DW_OP_reg18:
00448        case DW_OP_reg19:
00449        case DW_OP_reg20:
00450        case DW_OP_reg21:
00451        case DW_OP_reg22:
00452        case DW_OP_reg23:
00453        case DW_OP_reg24:
00454        case DW_OP_reg25:
00455        case DW_OP_reg26:
00456        case DW_OP_reg27:
00457        case DW_OP_reg28:
00458        case DW_OP_reg29:
00459        case DW_OP_reg30:
00460        case DW_OP_reg31:
00461          result = _Unwind_GetGR (context, op - DW_OP_reg0);
00462          break;
00463        case DW_OP_regx:
00464          op_ptr = read_uleb128 (op_ptr, &reg);
00465          result = _Unwind_GetGR (context, reg);
00466          break;
00467 
00468        case DW_OP_breg0:
00469        case DW_OP_breg1:
00470        case DW_OP_breg2:
00471        case DW_OP_breg3:
00472        case DW_OP_breg4:
00473        case DW_OP_breg5:
00474        case DW_OP_breg6:
00475        case DW_OP_breg7:
00476        case DW_OP_breg8:
00477        case DW_OP_breg9:
00478        case DW_OP_breg10:
00479        case DW_OP_breg11:
00480        case DW_OP_breg12:
00481        case DW_OP_breg13:
00482        case DW_OP_breg14:
00483        case DW_OP_breg15:
00484        case DW_OP_breg16:
00485        case DW_OP_breg17:
00486        case DW_OP_breg18:
00487        case DW_OP_breg19:
00488        case DW_OP_breg20:
00489        case DW_OP_breg21:
00490        case DW_OP_breg22:
00491        case DW_OP_breg23:
00492        case DW_OP_breg24:
00493        case DW_OP_breg25:
00494        case DW_OP_breg26:
00495        case DW_OP_breg27:
00496        case DW_OP_breg28:
00497        case DW_OP_breg29:
00498        case DW_OP_breg30:
00499        case DW_OP_breg31:
00500          op_ptr = read_sleb128 (op_ptr, &offset);
00501          result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
00502          break;
00503        case DW_OP_bregx:
00504          op_ptr = read_uleb128 (op_ptr, &reg);
00505          op_ptr = read_sleb128 (op_ptr, &offset);
00506          result = _Unwind_GetGR (context, reg) + offset;
00507          break;
00508 
00509        case DW_OP_dup:
00510          if (stack_elt < 1)
00511            abort ();
00512          result = stack[stack_elt - 1];
00513          break;
00514 
00515        case DW_OP_drop:
00516          if (--stack_elt < 0)
00517            abort ();
00518          goto no_push;
00519 
00520        case DW_OP_pick:
00521          offset = *op_ptr++;
00522          if (offset >= stack_elt - 1)
00523            abort ();
00524          result = stack[stack_elt - 1 - offset];
00525          break;
00526 
00527        case DW_OP_over:
00528          if (stack_elt < 2)
00529            abort ();
00530          result = stack[stack_elt - 2];
00531          break;
00532 
00533        case DW_OP_rot:
00534          {
00535            _Unwind_Word t1, t2, t3;
00536 
00537            if (stack_elt < 3)
00538              abort ();
00539            t1 = stack[stack_elt - 1];
00540            t2 = stack[stack_elt - 2];
00541            t3 = stack[stack_elt - 3];
00542            stack[stack_elt - 1] = t2;
00543            stack[stack_elt - 2] = t3;
00544            stack[stack_elt - 3] = t1;
00545            goto no_push;
00546          }
00547 
00548        case DW_OP_deref:
00549        case DW_OP_deref_size:
00550        case DW_OP_abs:
00551        case DW_OP_neg:
00552        case DW_OP_not:
00553        case DW_OP_plus_uconst:
00554          /* Unary operations.  */
00555          if (--stack_elt < 0)
00556            abort ();
00557          result = stack[stack_elt];
00558 
00559          switch (op)
00560            {
00561            case DW_OP_deref:
00562              {
00563               void *ptr = (void *) (_Unwind_Ptr) result;
00564               result = (_Unwind_Ptr) read_pointer (ptr);
00565              }
00566              break;
00567 
00568            case DW_OP_deref_size:
00569              {
00570               void *ptr = (void *) (_Unwind_Ptr) result;
00571               switch (*op_ptr++)
00572                 {
00573                 case 1:
00574                   result = read_1u (ptr);
00575                   break;
00576                 case 2:
00577                   result = read_2u (ptr);
00578                   break;
00579                 case 4:
00580                   result = read_4u (ptr);
00581                   break;
00582                 case 8:
00583                   result = read_8u (ptr);
00584                   break;
00585                 default:
00586                   abort ();
00587                 }
00588              }
00589              break;
00590 
00591            case DW_OP_abs:
00592              if ((_Unwind_Sword) result < 0)
00593               result = -result;
00594              break;
00595            case DW_OP_neg:
00596              result = -result;
00597              break;
00598            case DW_OP_not:
00599              result = ~result;
00600              break;
00601            case DW_OP_plus_uconst:
00602              op_ptr = read_uleb128 (op_ptr, &utmp);
00603              result += utmp;
00604              break;
00605 
00606            default:
00607              abort ();
00608            }
00609          break;
00610 
00611        case DW_OP_and:
00612        case DW_OP_div:
00613        case DW_OP_minus:
00614        case DW_OP_mod:
00615        case DW_OP_mul:
00616        case DW_OP_or:
00617        case DW_OP_plus:
00618        case DW_OP_le:
00619        case DW_OP_ge:
00620        case DW_OP_eq:
00621        case DW_OP_lt:
00622        case DW_OP_gt:
00623        case DW_OP_ne:
00624          {
00625            /* Binary operations.  */
00626            _Unwind_Word first, second;
00627            if ((stack_elt -= 2) < 0)
00628              abort ();
00629            second = stack[stack_elt];
00630            first = stack[stack_elt + 1];
00631 
00632            switch (op)
00633              {
00634              case DW_OP_and:
00635               result = second & first;
00636               break;
00637              case DW_OP_div:
00638               result = (_Unwind_Sword) second / (_Unwind_Sword) first;
00639               break;
00640              case DW_OP_minus:
00641               result = second - first;
00642               break;
00643              case DW_OP_mod:
00644               result = (_Unwind_Sword) second % (_Unwind_Sword) first;
00645               break;
00646              case DW_OP_mul:
00647               result = second * first;
00648               break;
00649              case DW_OP_or:
00650               result = second | first;
00651               break;
00652              case DW_OP_plus:
00653               result = second + first;
00654               break;
00655              case DW_OP_shl:
00656               result = second << first;
00657               break;
00658              case DW_OP_shr:
00659               result = second >> first;
00660               break;
00661              case DW_OP_shra:
00662               result = (_Unwind_Sword) second >> first;
00663               break;
00664              case DW_OP_xor:
00665               result = second ^ first;
00666               break;
00667              case DW_OP_le:
00668               result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
00669               break;
00670              case DW_OP_ge:
00671               result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
00672               break;
00673              case DW_OP_eq:
00674               result = (_Unwind_Sword) first == (_Unwind_Sword) second;
00675               break;
00676              case DW_OP_lt:
00677               result = (_Unwind_Sword) first < (_Unwind_Sword) second;
00678               break;
00679              case DW_OP_gt:
00680               result = (_Unwind_Sword) first > (_Unwind_Sword) second;
00681               break;
00682              case DW_OP_ne:
00683               result = (_Unwind_Sword) first != (_Unwind_Sword) second;
00684               break;
00685 
00686              default:
00687               abort ();
00688              }
00689          }
00690          break;
00691 
00692        case DW_OP_skip:
00693          offset = read_2s (op_ptr);
00694          op_ptr += 2;
00695          op_ptr += offset;
00696          goto no_push;
00697 
00698        case DW_OP_bra:
00699          if (--stack_elt < 0)
00700            abort ();
00701          offset = read_2s (op_ptr);
00702          op_ptr += 2;
00703          if (stack[stack_elt] != 0)
00704            op_ptr += offset;
00705          goto no_push;
00706 
00707        case DW_OP_nop:
00708          goto no_push;
00709 
00710        default:
00711          abort ();
00712        }
00713 
00714       /* Most things push a result value.  */
00715       if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
00716        abort ();
00717       stack[stack_elt++] = result;
00718     no_push:;
00719     }
00720 
00721   /* We were executing this program to get a value.  It should be
00722      at top of stack.  */
00723   if (--stack_elt < 0)
00724     abort ();
00725   return stack[stack_elt];
00726 }
00727 #endif
00728 
00729 /* Decode DWARF 2 call frame information. Takes pointers the
00730    instruction sequence to decode, current register information and
00731    CIE info, and the PC range to evaluate.  */
00732 
00733 static void
00734 execute_cfa_program (const unsigned char *insn_ptr,
00735                    const unsigned char *insn_end,
00736                    struct _Unwind_Context *context,
00737                    _Unwind_FrameState *fs)
00738 {
00739   struct frame_state_reg_info *unused_rs = NULL;
00740 
00741   /* Don't allow remember/restore between CIE and FDE programs.  */
00742   fs->regs.prev = NULL;
00743 
00744   /* The comparison with the return address uses < rather than <= because
00745      we are only interested in the effects of code before the call; for a
00746      noreturn function, the return address may point to unrelated code with
00747      a different stack configuration that we are not interested in.  We
00748      assume that the call itself is unwind info-neutral; if not, or if
00749      there are delay instructions that adjust the stack, these must be
00750      reflected at the point immediately before the call insn.  */
00751   while (insn_ptr < insn_end && fs->pc < context->ra)
00752     {
00753       unsigned char insn = *insn_ptr++;
00754       _Unwind_Word reg, utmp;
00755       _Unwind_Sword offset, stmp;
00756 
00757       if ((insn & 0xc0) == DW_CFA_advance_loc)
00758        fs->pc += (insn & 0x3f) * fs->code_align;
00759       else if ((insn & 0xc0) == DW_CFA_offset)
00760        {
00761          reg = insn & 0x3f;
00762          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00763          offset = (_Unwind_Sword) utmp * fs->data_align;
00764          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
00765          fs->regs.reg[reg].loc.offset = offset;
00766        }
00767       else if ((insn & 0xc0) == DW_CFA_restore)
00768        {
00769          reg = insn & 0x3f;
00770          fs->regs.reg[reg].how = REG_UNSAVED;
00771        }
00772       else switch (insn)
00773        {
00774        case DW_CFA_set_loc:
00775          {
00776            _Unwind_Ptr pc;
00777            insn_ptr = read_encoded_value (context, fs->fde_encoding,
00778                                       insn_ptr, &pc);
00779            fs->pc = (void *) pc;
00780          }
00781          break;
00782 
00783        case DW_CFA_advance_loc1:
00784          fs->pc += read_1u (insn_ptr) * fs->code_align;
00785          insn_ptr += 1;
00786          break;
00787        case DW_CFA_advance_loc2:
00788          fs->pc += read_2u (insn_ptr) * fs->code_align;
00789          insn_ptr += 2;
00790          break;
00791        case DW_CFA_advance_loc4:
00792          fs->pc += read_4u (insn_ptr) * fs->code_align;
00793          insn_ptr += 4;
00794          break;
00795 
00796        case DW_CFA_offset_extended:
00797          insn_ptr = read_uleb128 (insn_ptr, &reg);
00798          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00799          offset = (_Unwind_Sword) utmp * fs->data_align;
00800          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
00801          fs->regs.reg[reg].loc.offset = offset;
00802          break;
00803 
00804        case DW_CFA_restore_extended:
00805          insn_ptr = read_uleb128 (insn_ptr, &reg);
00806          fs->regs.reg[reg].how = REG_UNSAVED;
00807          break;
00808 
00809        case DW_CFA_undefined:
00810        case DW_CFA_same_value:
00811          insn_ptr = read_uleb128 (insn_ptr, &reg);
00812          break;
00813 
00814        case DW_CFA_nop:
00815          break;
00816 
00817        case DW_CFA_register:
00818          {
00819            _Unwind_Word reg2;
00820            insn_ptr = read_uleb128 (insn_ptr, &reg);
00821            insn_ptr = read_uleb128 (insn_ptr, &reg2);
00822            fs->regs.reg[reg].how = REG_SAVED_REG;
00823            fs->regs.reg[reg].loc.reg = reg2;
00824          }
00825          break;
00826 
00827        case DW_CFA_remember_state:
00828          {
00829            struct frame_state_reg_info *new_rs;
00830            if (unused_rs)
00831              {
00832               new_rs = unused_rs;
00833               unused_rs = unused_rs->prev;
00834              }
00835            else
00836              new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
00837 
00838            *new_rs = fs->regs;
00839            fs->regs.prev = new_rs;
00840          }
00841          break;
00842 
00843        case DW_CFA_restore_state:
00844          {
00845            struct frame_state_reg_info *old_rs = fs->regs.prev;
00846 #ifdef _LIBC
00847            if (old_rs == NULL)
00848              __libc_fatal ("invalid DWARF unwind data");
00849            else
00850 #endif
00851              {
00852               fs->regs = *old_rs;
00853               old_rs->prev = unused_rs;
00854               unused_rs = old_rs;
00855              }
00856          }
00857          break;
00858 
00859        case DW_CFA_def_cfa:
00860          insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
00861          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00862          fs->cfa_offset = utmp;
00863          fs->cfa_how = CFA_REG_OFFSET;
00864          break;
00865 
00866        case DW_CFA_def_cfa_register:
00867          insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
00868          fs->cfa_how = CFA_REG_OFFSET;
00869          break;
00870 
00871        case DW_CFA_def_cfa_offset:
00872          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00873          fs->cfa_offset = utmp;
00874          /* cfa_how deliberately not set.  */
00875          break;
00876 
00877        case DW_CFA_def_cfa_expression:
00878          fs->cfa_exp = insn_ptr;
00879          fs->cfa_how = CFA_EXP;
00880          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00881          insn_ptr += utmp;
00882          break;
00883 
00884        case DW_CFA_expression:
00885          insn_ptr = read_uleb128 (insn_ptr, &reg);
00886          fs->regs.reg[reg].how = REG_SAVED_EXP;
00887          fs->regs.reg[reg].loc.exp = insn_ptr;
00888          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00889          insn_ptr += utmp;
00890          break;
00891 
00892          /* From the 2.1 draft.  */
00893        case DW_CFA_offset_extended_sf:
00894          insn_ptr = read_uleb128 (insn_ptr, &reg);
00895          insn_ptr = read_sleb128 (insn_ptr, &stmp);
00896          offset = stmp * fs->data_align;
00897          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
00898          fs->regs.reg[reg].loc.offset = offset;
00899          break;
00900 
00901        case DW_CFA_def_cfa_sf:
00902          insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
00903          insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
00904          fs->cfa_how = CFA_REG_OFFSET;
00905          break;
00906 
00907        case DW_CFA_def_cfa_offset_sf:
00908          insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
00909          /* cfa_how deliberately not set.  */
00910          break;
00911 
00912        case DW_CFA_GNU_window_save:
00913          /* ??? Hardcoded for SPARC register window configuration.
00914             At least do not do anything for archs which explicitly
00915             define a lower register number.  */
00916 #if DWARF_FRAME_REGISTERS >= 32
00917          for (reg = 16; reg < 32; ++reg)
00918            {
00919              fs->regs.reg[reg].how = REG_SAVED_OFFSET;
00920              fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
00921            }
00922 #endif
00923          break;
00924 
00925        case DW_CFA_GNU_args_size:
00926          insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
00927          break;
00928 
00929        case DW_CFA_GNU_negative_offset_extended:
00930          /* Obsoleted by DW_CFA_offset_extended_sf, but used by
00931             older PowerPC code.  */
00932          insn_ptr = read_uleb128 (insn_ptr, &reg);
00933          insn_ptr = read_uleb128 (insn_ptr, &utmp);
00934          offset = (_Unwind_Word) utmp * fs->data_align;
00935          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
00936          fs->regs.reg[reg].loc.offset = -offset;
00937          break;
00938 
00939        default:
00940          abort ();
00941        }
00942     }
00943 }
00944 
00945 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
00946    its caller and decode it into FS.  This function also sets the
00947    args_size and lsda members of CONTEXT, as they are really information
00948    about the caller's frame.  */
00949 
00950 static _Unwind_Reason_Code
00951 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
00952 {
00953   struct dwarf_fde *fde;
00954   struct dwarf_cie *cie;
00955   const unsigned char *aug, *insn, *end;
00956 
00957   memset (fs, 0, sizeof (*fs));
00958   context->args_size = 0;
00959   context->lsda = 0;
00960 
00961   fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
00962   if (fde == NULL)
00963     {
00964       /* Couldn't find frame unwind info for this function.  Try a
00965         target-specific fallback mechanism.  This will necessarily
00966         not provide a personality routine or LSDA.  */
00967 #ifdef MD_FALLBACK_FRAME_STATE_FOR
00968       MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
00969       return _URC_END_OF_STACK;
00970     success:
00971       return _URC_NO_REASON;
00972 #else
00973       return _URC_END_OF_STACK;
00974 #endif
00975     }
00976 
00977   fs->pc = context->bases.func;
00978 
00979   cie = get_cie (fde);
00980   insn = extract_cie_info (cie, context, fs);
00981   if (insn == NULL)
00982     /* CIE contained unknown augmentation.  */
00983     return _URC_FATAL_PHASE1_ERROR;
00984 
00985   /* First decode all the insns in the CIE.  */
00986   end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
00987   execute_cfa_program (insn, end, context, fs);
00988 
00989   /* Locate augmentation for the fde.  */
00990   aug = (unsigned char *) fde + sizeof (*fde);
00991   aug += 2 * size_of_encoded_value (fs->fde_encoding);
00992   insn = NULL;
00993   if (fs->saw_z)
00994     {
00995       _Unwind_Word i;
00996       aug = read_uleb128 (aug, &i);
00997       insn = aug + i;
00998     }
00999   if (fs->lsda_encoding != DW_EH_PE_omit)
01000     {
01001       _Unwind_Ptr lsda;
01002       aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
01003       context->lsda = (void *) lsda;
01004     }
01005 
01006   /* Then the insns in the FDE up to our target PC.  */
01007   if (insn == NULL)
01008     insn = aug;
01009   end = (unsigned char *) next_fde (fde);
01010   execute_cfa_program (insn, end, context, fs);
01011 
01012   return _URC_NO_REASON;
01013 }
01014 
01015 typedef struct frame_state
01016 {
01017   void *cfa;
01018   void *eh_ptr;
01019   long cfa_offset;
01020   long args_size;
01021   long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
01022   unsigned short cfa_reg;
01023   unsigned short retaddr_column;
01024   char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
01025 } frame_state;
01026 
01027 #ifndef STATIC
01028 # define STATIC
01029 #endif
01030 
01031 STATIC
01032 struct frame_state * __frame_state_for (void *, struct frame_state *);
01033 
01034 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
01035    a given PC_TARGET.  The caller should allocate a local variable of
01036    `struct frame_state' and pass its address to STATE_IN.  */
01037 
01038 STATIC
01039 struct frame_state *
01040 __frame_state_for (void *pc_target, struct frame_state *state_in)
01041 {
01042   struct _Unwind_Context context;
01043   _Unwind_FrameState fs;
01044   int reg;
01045 
01046   memset (&context, 0, sizeof (struct _Unwind_Context));
01047   context.ra = pc_target + 1;
01048 
01049   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
01050     return 0;
01051 
01052   /* We have no way to pass a location expression for the CFA to our
01053      caller.  It wouldn't understand it anyway.  */
01054   if (fs.cfa_how == CFA_EXP)
01055     return 0;
01056 
01057   for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
01058     {
01059       state_in->saved[reg] = fs.regs.reg[reg].how;
01060       switch (state_in->saved[reg])
01061        {
01062        case REG_SAVED_REG:
01063          state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
01064          break;
01065        case REG_SAVED_OFFSET:
01066          state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
01067          break;
01068        default:
01069          state_in->reg_or_offset[reg] = 0;
01070          break;
01071        }
01072     }
01073 
01074   state_in->cfa_offset = fs.cfa_offset;
01075   state_in->cfa_reg = fs.cfa_reg;
01076   state_in->retaddr_column = fs.retaddr_column;
01077   state_in->args_size = context.args_size;
01078   state_in->eh_ptr = fs.eh_ptr;
01079 
01080   return state_in;
01081 }
01082 
01083 #ifndef _LIBC
01084 
01085 static void
01086 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
01087 {
01088   struct _Unwind_Context orig_context = *context;
01089   void *cfa;
01090   long i;
01091 
01092 #ifdef EH_RETURN_STACKADJ_RTX
01093   /* Special handling here: Many machines do not use a frame pointer,
01094      and track the CFA only through offsets from the stack pointer from
01095      one frame to the next.  In this case, the stack pointer is never
01096      stored, so it has no saved address in the context.  What we do
01097      have is the CFA from the previous stack frame.
01098 
01099      In very special situations (such as unwind info for signal return),
01100      there may be location expressions that use the stack pointer as well.
01101 
01102      Do this conditionally for one frame.  This allows the unwind info
01103      for one frame to save a copy of the stack pointer from the previous
01104      frame, and be able to use much easier CFA mechanisms to do it.
01105      Always zap the saved stack pointer value for the next frame; carrying
01106      the value over from one frame to another doesn't make sense.  */
01107 
01108   _Unwind_Word tmp_sp;
01109 
01110   if (!orig_context.reg[__builtin_dwarf_sp_column ()])
01111     {
01112       tmp_sp = (_Unwind_Ptr) context->cfa;
01113       orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
01114     }
01115   context->reg[__builtin_dwarf_sp_column ()] = NULL;
01116 #endif
01117 
01118   /* Compute this frame's CFA.  */
01119   switch (fs->cfa_how)
01120     {
01121     case CFA_REG_OFFSET:
01122       cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
01123       cfa += fs->cfa_offset;
01124       break;
01125 
01126     case CFA_EXP:
01127       {
01128        const unsigned char *exp = fs->cfa_exp;
01129        _Unwind_Word len;
01130 
01131        exp = read_uleb128 (exp, &len);
01132        cfa = (void *) (_Unwind_Ptr)
01133          execute_stack_op (exp, exp + len, &orig_context, 0);
01134        break;
01135       }
01136 
01137     default:
01138       abort ();
01139     }
01140   context->cfa = cfa;
01141 
01142   /* Compute the addresses of all registers saved in this frame.  */
01143   for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
01144     switch (fs->regs.reg[i].how)
01145       {
01146       case REG_UNSAVED:
01147        break;
01148 
01149       case REG_SAVED_OFFSET:
01150        context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
01151        break;
01152 
01153       case REG_SAVED_REG:
01154        context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
01155        break;
01156 
01157       case REG_SAVED_EXP:
01158        {
01159          const unsigned char *exp = fs->regs.reg[i].loc.exp;
01160          _Unwind_Word len;
01161          _Unwind_Ptr val;
01162 
01163          exp = read_uleb128 (exp, &len);
01164          val = execute_stack_op (exp, exp + len, &orig_context,
01165                               (_Unwind_Ptr) cfa);
01166          context->reg[i] = (void *) val;
01167        }
01168        break;
01169       }
01170 }
01171 
01172 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
01173    of its caller.  Update CONTEXT to refer to the caller as well.  Note
01174    that the args_size and lsda members are not updated here, but later in
01175    uw_frame_state_for.  */
01176 
01177 static void
01178 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
01179 {
01180   uw_update_context_1 (context, fs);
01181 
01182   /* Compute the return address now, since the return address column
01183      can change from frame to frame.  */
01184   context->ra = __builtin_extract_return_addr
01185     ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
01186 }
01187 
01188 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
01189    level will be the return address and the CFA.  */
01190 
01191 #define uw_init_context(CONTEXT)                                  \
01192   do                                                              \
01193     {                                                             \
01194       /* Do any necessary initialization to access arbitrary stack frames. \
01195         On the SPARC, this means flushing the register windows.  */      \
01196       __builtin_unwind_init ();                                          \
01197       uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                \
01198                       __builtin_return_address (0));                     \
01199     }                                                             \
01200   while (0)
01201 
01202 static void
01203 uw_init_context_1 (struct _Unwind_Context *context,
01204                  void *outer_cfa, void *outer_ra)
01205 {
01206   void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
01207   _Unwind_FrameState fs;
01208   _Unwind_Word sp_slot;
01209 
01210   memset (context, 0, sizeof (struct _Unwind_Context));
01211   context->ra = ra;
01212 
01213   if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
01214     abort ();
01215 
01216   /* Force the frame state to use the known cfa value.  */
01217   sp_slot = (_Unwind_Ptr) outer_cfa;
01218   context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
01219   fs.cfa_how = CFA_REG_OFFSET;
01220   fs.cfa_reg = __builtin_dwarf_sp_column ();
01221   fs.cfa_offset = 0;
01222 
01223   uw_update_context_1 (context, &fs);
01224 
01225   /* If the return address column was saved in a register in the
01226      initialization context, then we can't see it in the given
01227      call frame data.  So have the initialization context tell us.  */
01228   context->ra = __builtin_extract_return_addr (outer_ra);
01229 }
01230 
01231 
01232 /* Install TARGET into CURRENT so that we can return to it.  This is a
01233    macro because __builtin_eh_return must be invoked in the context of
01234    our caller.  */
01235 
01236 #define uw_install_context(CURRENT, TARGET)                            \
01237   do                                                            \
01238     {                                                           \
01239       long offset = uw_install_context_1 ((CURRENT), (TARGET));               \
01240       void *handler = __builtin_frob_return_addr ((TARGET)->ra);       \
01241       __builtin_eh_return (offset, handler);                           \
01242     }                                                           \
01243   while (0)
01244 
01245 static inline void
01246 init_dwarf_reg_size_table (void)
01247 {
01248   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
01249 }
01250 
01251 static long
01252 uw_install_context_1 (struct _Unwind_Context *current,
01253                     struct _Unwind_Context *target)
01254 {
01255   long i;
01256 
01257 #if __GTHREADS
01258   {
01259     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
01260     if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
01261        || dwarf_reg_size_table[0] == 0)
01262       init_dwarf_reg_size_table ();
01263   }
01264 #else
01265   if (dwarf_reg_size_table[0] == 0)
01266     init_dwarf_reg_size_table ();
01267 #endif
01268 
01269   for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
01270     {
01271       void *c = current->reg[i];
01272       void *t = target->reg[i];
01273       if (t && c && t != c)
01274        memcpy (c, t, dwarf_reg_size_table[i]);
01275     }
01276 
01277 #ifdef EH_RETURN_STACKADJ_RTX
01278   {
01279     void *target_cfa;
01280 
01281     /* If the last frame records a saved stack pointer, use it.  */
01282     if (target->reg[__builtin_dwarf_sp_column ()])
01283       target_cfa = (void *)(_Unwind_Ptr)
01284         _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
01285     else
01286       target_cfa = target->cfa;
01287 
01288     /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
01289     if (STACK_GROWS_DOWNWARD)
01290       return target_cfa - current->cfa + target->args_size;
01291     else
01292       return current->cfa - target_cfa - target->args_size;
01293   }
01294 #else
01295   return 0;
01296 #endif
01297 }
01298 
01299 static inline _Unwind_Ptr
01300 uw_identify_context (struct _Unwind_Context *context)
01301 {
01302   return _Unwind_GetIP (context);
01303 }
01304 
01305 
01306 #include "unwind.inc"
01307 
01308 #endif /* _LIBC */