]> sourceware.org Git - glibc.git/commitdiff
Update from recent gcc version.
authorUlrich Drepper <drepper@redhat.com>
Sun, 13 Apr 2003 16:45:10 +0000 (16:45 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 13 Apr 2003 16:45:10 +0000 (16:45 +0000)
sysdeps/generic/unwind-dw2-fde.c
sysdeps/generic/unwind-dw2-fde.h
sysdeps/generic/unwind-dw2.c
sysdeps/generic/unwind-pe.h

index 6c51c6f7305a0c58d761f7207d62f5ca9cf9eae6..64c0846ccbb4d4f1f3d3d16ba8b307d7421fdb11 100644 (file)
@@ -1,13 +1,13 @@
 /* Subroutines needed for unwinding stack frames for exception handling.  */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Jason Merrill <jason@cygnus.com>.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
 In addition to the permissions in the GNU General Public License, the
 Free Software Foundation gives you unlimited permission to link the
@@ -18,15 +18,15 @@ do apply in other respects; for example, they cover modification of
 the file, and distribution when not linked into a combine
 executable.)
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 #ifdef _LIBC
 # include <shlib-compat.h>
@@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #include <unwind-pe.h>
 #include <unwind-dw2-fde.h>
 #else
+#ifndef _Unwind_Find_FDE
 #include "tconfig.h"
 #include "tsystem.h"
 #include "dwarf2.h"
@@ -53,6 +54,7 @@ Boston, MA 02111-1307, USA.  */
 #include "unwind-dw2-fde.h"
 #include "gthr.h"
 #endif
+#endif
 
 /* The unseen_objects list contains objects that have been registered
    but not yet categorized in any way.  The seen_objects list has had
@@ -109,7 +111,7 @@ __register_frame_info_bases (void *begin, struct object *ob,
                             void *tbase, void *dbase)
 {
   /* If .eh_frame is empty, don't register at all.  */
-  if (*(uword *)begin == 0)
+  if (*(uword *) begin == 0)
     return;
 
   ob->pc_begin = (void *)-1;
@@ -118,6 +120,9 @@ __register_frame_info_bases (void *begin, struct object *ob,
   ob->u.single = begin;
   ob->s.i = 0;
   ob->s.b.encoding = DW_EH_PE_omit;
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+  ob->fde_end = NULL;
+#endif
 
   init_object_mutex_once ();
   __gthread_mutex_lock (&object_mutex);
@@ -141,7 +146,7 @@ __register_frame (void *begin)
   struct object *ob;
 
   /* If .eh_frame is empty, don't register at all.  */
-  if (*(uword *)begin == 0)
+  if (*(uword *) begin == 0)
     return;
 
   ob = (struct object *) malloc (sizeof (struct object));
@@ -206,7 +211,7 @@ __deregister_frame_info_bases (void *begin)
   struct object *ob = 0;
 
   /* If .eh_frame is empty, we haven't registered.  */
-  if (*(uword *)begin == 0)
+  if (*(uword *) begin == 0)
     return ob;
 
   init_object_mutex_once ();
@@ -260,7 +265,7 @@ void
 __deregister_frame (void *begin)
 {
   /* If .eh_frame is empty, we haven't registered.  */
-  if (*(uword *)begin != 0)
+  if (*(uword *) begin != 0)
     free (INTUSE(__deregister_frame_info_bases) (begin));
 }
 
@@ -297,18 +302,20 @@ get_cie_encoding (struct dwarf_cie *cie)
 {
   const unsigned char *aug, *p;
   _Unwind_Ptr dummy;
+  _Unwind_Word utmp;
+  _Unwind_Sword stmp;
 
   aug = cie->augmentation;
   if (aug[0] != 'z')
     return DW_EH_PE_absptr;
 
   p = aug + strlen (aug) + 1;          /* Skip the augmentation string.  */
-  p = read_uleb128 (p, &dummy);                /* Skip code alignment.  */
-  p = read_sleb128 (p, &dummy);                /* Skip data alignment.  */
+  p = read_uleb128 (p, &utmp);         /* Skip code alignment.  */
+  p = read_sleb128 (p, &stmp);         /* Skip data alignment.  */
   p++;                                 /* Skip return address column.  */
 
   aug++;                               /* Skip 'z' */
-  p = read_uleb128 (p, &dummy);                /* Skip augmentation length.  */
+  p = read_uleb128 (p, &utmp);         /* Skip augmentation length.  */
   while (1)
     {
       /* This is what we're looking for.  */
@@ -345,14 +352,21 @@ get_fde_encoding (struct dwarf_fde *f)
 
 /* Comparison routines.  Three variants of increasing complexity.  */
 
-static saddr
+static int
 fde_unencoded_compare (struct object *ob __attribute__((unused)),
                       fde *x, fde *y)
 {
-  return *(saddr *)x->pc_begin - *(saddr *)y->pc_begin;
+  _Unwind_Ptr x_ptr = *(_Unwind_Ptr *) x->pc_begin;
+  _Unwind_Ptr y_ptr = *(_Unwind_Ptr *) y->pc_begin;
+
+  if (x_ptr > y_ptr)
+    return 1;
+  if (x_ptr < y_ptr)
+    return -1;
+  return 0;
 }
 
-static saddr
+static int
 fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
 {
   _Unwind_Ptr base, x_ptr, y_ptr;
@@ -361,10 +375,14 @@ fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
   read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
   read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
 
-  return x_ptr - y_ptr;
+  if (x_ptr > y_ptr)
+    return 1;
+  if (x_ptr < y_ptr)
+    return -1;
+  return 0;
 }
 
-static saddr
+static int
 fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
 {
   int x_encoding, y_encoding;
@@ -378,10 +396,14 @@ fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
   read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
                                y->pc_begin, &y_ptr);
 
-  return x_ptr - y_ptr;
+  if (x_ptr > y_ptr)
+    return 1;
+  if (x_ptr < y_ptr)
+    return -1;
+  return 0;
 }
 
-typedef saddr (*fde_compare_t) (struct object *, fde *, fde *);
+typedef int (*fde_compare_t) (struct object *, fde *, fde *);
 
 
 /* This is a special mix of insertion sort and heap sort, optimized for
@@ -459,13 +481,13 @@ fde_split (struct object *ob, fde_compare_t fde_compare,
       fde **probe;
 
       for (probe = chain_end;
-           probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
-           probe = chain_end)
-        {
-          chain_end = (fde **)erratic->array[probe - linear->array];
-          erratic->array[probe - linear->array] = NULL;
-        }
-      erratic->array[i] = (fde *)chain_end;
+          probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
+          probe = chain_end)
+       {
+         chain_end = (fde **) erratic->array[probe - linear->array];
+         erratic->array[probe - linear->array] = NULL;
+       }
+      erratic->array[i] = (fde *) chain_end;
       chain_end = &linear->array[i];
     }
 
@@ -490,11 +512,11 @@ frame_heapsort (struct object *ob, fde_compare_t fde_compare,
 {
   /* For a description of this algorithm, see:
      Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
-     p. 60-61. */
+     p. 60-61.  */
   fde ** a = erratic->array;
   /* A portion of the array is called a "heap" if for all i>=0:
      If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
-     If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
+     If i and 2i+2 are valid indices, then a[i] >= a[2i+2].  */
 #define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
   size_t n = erratic->count;
   size_t m = n;
@@ -502,53 +524,53 @@ frame_heapsort (struct object *ob, fde_compare_t fde_compare,
 
   while (m > 0)
     {
-      /* Invariant: a[m..n-1] is a heap. */
+      /* Invariant: a[m..n-1] is a heap.  */
       m--;
       for (i = m; 2*i+1 < n; )
-        {
-          if (2*i+2 < n
-              && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
-              && fde_compare (ob, a[2*i+2], a[i]) > 0)
-            {
-              SWAP (a[i], a[2*i+2]);
-              i = 2*i+2;
-            }
-          else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
-            {
-              SWAP (a[i], a[2*i+1]);
-              i = 2*i+1;
-            }
-          else
-            break;
-        }
+       {
+         if (2*i+2 < n
+             && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
+             && fde_compare (ob, a[2*i+2], a[i]) > 0)
+           {
+             SWAP (a[i], a[2*i+2]);
+             i = 2*i+2;
+           }
+         else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
+           {
+             SWAP (a[i], a[2*i+1]);
+             i = 2*i+1;
+           }
+         else
+           break;
+       }
     }
   while (n > 1)
     {
-      /* Invariant: a[0..n-1] is a heap. */
+      /* Invariant: a[0..n-1] is a heap.  */
       n--;
       SWAP (a[0], a[n]);
       for (i = 0; 2*i+1 < n; )
-        {
-          if (2*i+2 < n
-              && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
-              && fde_compare (ob, a[2*i+2], a[i]) > 0)
-            {
-              SWAP (a[i], a[2*i+2]);
-              i = 2*i+2;
-            }
-          else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
-            {
-              SWAP (a[i], a[2*i+1]);
-              i = 2*i+1;
-            }
-          else
-            break;
-        }
+       {
+         if (2*i+2 < n
+             && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
+             && fde_compare (ob, a[2*i+2], a[i]) > 0)
+           {
+             SWAP (a[i], a[2*i+2]);
+             i = 2*i+2;
+           }
+         else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
+           {
+             SWAP (a[i], a[2*i+1]);
+             i = 2*i+1;
+           }
+         else
+           break;
+       }
     }
 #undef SWAP
 }
 
-/* Merge V1 and V2, both sorted, and put the result into V1. */
+/* Merge V1 and V2, both sorted, and put the result into V1.  */
 static inline void
 fde_merge (struct object *ob, fde_compare_t fde_compare,
           struct fde_vector *v1, struct fde_vector *v2)
@@ -560,16 +582,18 @@ fde_merge (struct object *ob, fde_compare_t fde_compare,
   if (i2 > 0)
     {
       i1 = v1->count;
-      do {
-        i2--;
-        fde2 = v2->array[i2];
-        while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
-          {
-            v1->array[i1+i2] = v1->array[i1-1];
-            i1--;
-          }
-        v1->array[i1+i2] = fde2;
-      } while (i2 > 0);
+      do
+       {
+         i2--;
+         fde2 = v2->array[i2];
+         while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
+           {
+             v1->array[i1+i2] = v1->array[i1-1];
+             i1--;
+           }
+         v1->array[i1+i2] = fde2;
+       }
+      while (i2 > 0);
       v1->count += v2->count;
     }
 }
@@ -619,7 +643,7 @@ classify_object_over_fdes (struct object *ob, fde *this_fde)
   int encoding = DW_EH_PE_absptr;
   _Unwind_Ptr base = 0;
 
-  for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+  for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
     {
       struct dwarf_cie *this_cie;
       _Unwind_Ptr mask, pc_begin;
@@ -659,8 +683,8 @@ classify_object_over_fdes (struct object *ob, fde *this_fde)
        continue;
 
       count += 1;
-      if ((void *)pc_begin < ob->pc_begin)
-       ob->pc_begin = (void *)pc_begin;
+      if ((void *) pc_begin < ob->pc_begin)
+       ob->pc_begin = (void *) pc_begin;
     }
 
   return count;
@@ -673,7 +697,7 @@ add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
   int encoding = ob->s.b.encoding;
   _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
 
-  for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+  for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
     {
       struct dwarf_cie *this_cie;
 
@@ -696,7 +720,7 @@ add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
 
       if (encoding == DW_EH_PE_absptr)
        {
-         if (*(_Unwind_Ptr *)this_fde->pc_begin == 0)
+         if (*(_Unwind_Ptr *) this_fde->pc_begin == 0)
            continue;
        }
       else
@@ -764,7 +788,7 @@ init_object (struct object* ob)
     {
       fde **p;
       for (p = ob->u.array; *p; ++p)
-        add_fdes (ob, &accu, *p);
+       add_fdes (ob, &accu, *p);
     }
   else
     add_fdes (ob, &accu, ob->u.single);
@@ -790,7 +814,7 @@ linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
   int encoding = ob->s.b.encoding;
   _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
 
-  for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+  for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
     {
       struct dwarf_cie *this_cie;
       _Unwind_Ptr pc_begin, pc_range;
@@ -814,8 +838,8 @@ linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
 
       if (encoding == DW_EH_PE_absptr)
        {
-         pc_begin = ((_Unwind_Ptr *)this_fde->pc_begin)[0];
-         pc_range = ((_Unwind_Ptr *)this_fde->pc_begin)[1];
+         pc_begin = ((_Unwind_Ptr *) this_fde->pc_begin)[0];
+         pc_range = ((_Unwind_Ptr *) this_fde->pc_begin)[1];
          if (pc_begin == 0)
            continue;
        }
@@ -842,8 +866,8 @@ linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
            continue;
        }
 
-      if ((_Unwind_Ptr)pc - pc_begin < pc_range)
-        return this_fde;
+      if ((_Unwind_Ptr) pc - pc_begin < pc_range)
+       return this_fde;
     }
 
   return NULL;
@@ -865,8 +889,8 @@ binary_search_unencoded_fdes (struct object *ob, void *pc)
       void *pc_begin;
       uaddr pc_range;
 
-      pc_begin = ((void **)f->pc_begin)[0];
-      pc_range = ((uaddr *)f->pc_begin)[1];
+      pc_begin = ((void **) f->pc_begin)[0];
+      pc_range = ((uaddr *) f->pc_begin)[1];
 
       if (pc < pc_begin)
        hi = i;
@@ -898,9 +922,9 @@ binary_search_single_encoding_fdes (struct object *ob, void *pc)
                                        &pc_begin);
       read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
 
-      if ((_Unwind_Ptr)pc < pc_begin)
+      if ((_Unwind_Ptr) pc < pc_begin)
        hi = i;
-      else if ((_Unwind_Ptr)pc >= pc_begin + pc_range)
+      else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
        lo = i + 1;
       else
        return f;
@@ -929,9 +953,9 @@ binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
                                        f->pc_begin, &pc_begin);
       read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
 
-      if ((_Unwind_Ptr)pc < pc_begin)
+      if ((_Unwind_Ptr) pc < pc_begin)
        hi = i;
-      else if ((_Unwind_Ptr)pc >= pc_begin + pc_range)
+      else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
        lo = i + 1;
       else
        return f;
@@ -969,14 +993,14 @@ search_object (struct object* ob, void *pc)
     {
       /* Long slow labourious linear search, cos we've no memory.  */
       if (ob->s.b.from_array)
-        {
-          fde **p;
+       {
+         fde **p;
          for (p = ob->u.array; *p ; p++)
            {
              fde *f = linear_search_fdes (ob, *p, pc);
-              if (f)
+             if (f)
                return f;
-            }
+           }
          return NULL;
        }
       else
index 83b4470ce5a280002a6cb123838062d34d7eb95c..4fc4836d2a55b63750475c6d7a8c4dc9d4966d51 100644 (file)
@@ -1,13 +1,14 @@
 /* Subroutines needed for unwinding stack frames for exception handling.  */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
    Contributed by Jason Merrill <jason@cygnus.com>.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
 In addition to the permissions in the GNU General Public License, the
 Free Software Foundation gives you unlimited permission to link the
@@ -18,15 +19,15 @@ do apply in other respects; for example, they cover modification of
 the file, and distribution when not linked into a combine
 executable.)
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 
 struct fde_vector
@@ -57,12 +58,16 @@ struct object
       unsigned long mixed_encoding : 1;
       unsigned long encoding : 8;
       /* ??? Wish there was an easy way to detect a 64-bit host here;
-        we've got 32 bits left to play with... */
+        we've got 32 bits left to play with...  */
       unsigned long count : 21;
     } b;
     size_t i;
   } s;
 
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+  char *fde_end;
+#endif
+
   struct object *next;
 };
 #endif
@@ -116,7 +121,7 @@ typedef unsigned char ubyte;
    is located, and what the register lifetimes and stack layout are
    within the function.
 
-   The data structures are defined in the DWARF specfication, although
+   The data structures are defined in the DWARF specification, although
    not in a very readable way (see LITERATURE).
 
    Every time an exception is thrown, the code needs to locate the FDE
@@ -125,7 +130,7 @@ typedef unsigned char ubyte;
    a) in a linear search, find the shared image (i.e. DLL) containing
       the PC
    b) using the FDE table for that shared object, locate the FDE using
-      binary search (which requires the sorting).  */   
+      binary search (which requires the sorting).  */
 
 /* The first few fields of a CIE.  The CIE_id field is 0 for a CIE,
    to distinguish it from a valid FDE.  FDEs are aligned to an addressing
@@ -159,7 +164,17 @@ get_cie (struct dwarf_fde *f)
 static inline fde *
 next_fde (fde *f)
 {
-  return (fde *)((char *)f + f->length + sizeof (f->length));
+  return (fde *) ((char *) f + f->length + sizeof (f->length));
 }
 
 extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
+
+static inline int
+last_fde (struct object *obj __attribute__ ((__unused__)), fde *f)
+{
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+  return (char *)f == obj->fde_end || f->length == 0;
+#else
+  return f->length == 0;
+#endif
+}
index 3a53156621b80f122a92fe0c6ab79770938061ba..720034427d5f9407a6dca707a0f2cc6a249ce85b 100644 (file)
@@ -1,22 +1,23 @@
 /* DWARF2 exception handling and frame unwind runtime interface routines.
-   Copyright (C) 1997,1998,1999,2000,2001,2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
 
-   This file is part of GNU CC.
+   This file is part of GCC.
 
-   GNU CC is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.
 
-   GNU CC is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GNU CC; see the file COPYING.  If not, write to
-   the Free Software Foundation, 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 #ifdef _LIBC
 #include <stdlib.h>
@@ -37,7 +38,8 @@
 #include "gthr.h"
 #endif
 
-#if !USING_SJLJ_EXCEPTIONS
+
+#ifndef __USING_SJLJ_EXCEPTIONS__
 
 #ifndef STACK_GROWS_DOWNWARD
 #define STACK_GROWS_DOWNWARD 0
 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
 #endif
 
-/* This is the register and unwind state for a particular frame.  */
+/* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
+#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
+#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
+#endif
+
+/* This is the register and unwind state for a particular frame.  This
+   provides the information necessary to unwind up past a frame and return
+   to its caller.  */
 struct _Unwind_Context
 {
   void *reg[DWARF_FRAME_REGISTERS+1];
@@ -80,7 +89,7 @@ typedef struct
   {
     struct {
       union {
-       unsigned int reg;
+       _Unwind_Word reg;
        _Unwind_Sword offset;
        const unsigned char *exp;
       } loc;
@@ -112,8 +121,8 @@ typedef struct
 
   /* The information we care about from the CIE/FDE.  */
   _Unwind_Personality_Fn personality;
-  signed int data_align;
-  unsigned int code_align;
+  _Unwind_Sword data_align;
+  _Unwind_Word code_align;
   unsigned char retaddr_column;
   unsigned char fde_encoding;
   unsigned char lsda_encoding;
@@ -138,10 +147,10 @@ static inline void *
 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
 
 static inline int
-read_1u (const void *p) { return *(const unsigned char *)p; }
+read_1u (const void *p) { return *(const unsigned char *) p; }
 
 static inline int
-read_1s (const void *p) { return *(const signed char *)p; }
+read_1s (const void *p) { return *(const signed char *) p; }
 
 static inline int
 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
@@ -170,6 +179,14 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
   return * (_Unwind_Word *) context->reg[index];
 }
 
+/* Get the value of the CFA as saved in CONTEXT.  */
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+  return context->cfa;
+}
+
 /* Overwrite the saved value for register REG in CONTEXT with VAL.  */
 
 inline void
@@ -206,6 +223,17 @@ _Unwind_GetRegionStart (struct _Unwind_Context *context)
   return (_Unwind_Ptr) context->bases.func;
 }
 
+void *
+_Unwind_FindEnclosingFunction (void *pc)
+{
+  struct dwarf_eh_bases bases;
+  struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
+  if (fde)
+    return bases.func;
+  else
+    return NULL;
+}
+
 #ifndef __ia64__
 _Unwind_Ptr
 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
@@ -231,7 +259,7 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
   const unsigned char *aug = cie->augmentation;
   const unsigned char *p = aug + strlen (aug) + 1;
   const unsigned char *ret = NULL;
-  _Unwind_Ptr tmp;
+  _Unwind_Word utmp;
 
   /* g++ v2 "eh" has pointer immediately following augmentation string,
      so it must be handled first.  */
@@ -244,8 +272,8 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
 
   /* Immediately following the augmentation are the code and
      data alignment and return address column.  */
-  p = read_uleb128 (p, &tmp); fs->code_align = tmp;
-  p = read_sleb128 (p, &tmp); fs->data_align = (saddr) tmp;
+  p = read_uleb128 (p, &fs->code_align);
+  p = read_sleb128 (p, &fs->data_align);
   fs->retaddr_column = *p++;
   fs->lsda_encoding = DW_EH_PE_omit;
 
@@ -254,8 +282,8 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
      the size.  */
   if (*aug == 'z')
     {
-      p = read_uleb128 (p, &tmp);
-      ret = p + tmp;
+      p = read_uleb128 (p, &utmp);
+      ret = p + utmp;
 
       fs->saw_z = 1;
       ++aug;
@@ -303,7 +331,7 @@ static _Unwind_Word
 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
                  struct _Unwind_Context *context, _Unwind_Word initial)
 {
-  _Unwind_Word stack[64];      /* ??? Assume this is enough. */
+  _Unwind_Word stack[64];      /* ??? Assume this is enough.  */
   int stack_elt;
 
   stack[0] = initial;
@@ -312,9 +340,8 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
   while (op_ptr < op_end)
     {
       enum dwarf_location_atom op = *op_ptr++;
-      _Unwind_Word result = 0, reg;
-      _Unwind_Sword offset;
-      _Unwind_Ptr ptrtmp;
+      _Unwind_Word result, reg, utmp;
+      _Unwind_Sword offset, stmp;
 
       switch (op)
        {
@@ -391,12 +418,11 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
          op_ptr += 8;
          break;
        case DW_OP_constu:
-         op_ptr = read_uleb128 (op_ptr, &ptrtmp);
-         result = ptrtmp;
+         op_ptr = read_uleb128 (op_ptr, &result);
          break;
        case DW_OP_consts:
-         op_ptr = read_sleb128 (op_ptr, &ptrtmp);
-         result = (saddr)ptrtmp;
+         op_ptr = read_sleb128 (op_ptr, &stmp);
+         result = stmp;
          break;
 
        case DW_OP_reg0:
@@ -434,7 +460,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
          result = _Unwind_GetGR (context, op - DW_OP_reg0);
          break;
        case DW_OP_regx:
-         op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
+         op_ptr = read_uleb128 (op_ptr, &reg);
          result = _Unwind_GetGR (context, reg);
          break;
 
@@ -470,12 +496,12 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
        case DW_OP_breg29:
        case DW_OP_breg30:
        case DW_OP_breg31:
-         op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
+         op_ptr = read_sleb128 (op_ptr, &offset);
          result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
          break;
        case DW_OP_bregx:
-         op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
-         op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
+         op_ptr = read_uleb128 (op_ptr, &reg);
+         op_ptr = read_sleb128 (op_ptr, &offset);
          result = _Unwind_GetGR (context, reg) + offset;
          break;
 
@@ -533,14 +559,14 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
            {
            case DW_OP_deref:
              {
-               void *ptr = (void *)(_Unwind_Ptr) result;
+               void *ptr = (void *) (_Unwind_Ptr) result;
                result = (_Unwind_Ptr) read_pointer (ptr);
              }
              break;
 
            case DW_OP_deref_size:
              {
-               void *ptr = (void *)(_Unwind_Ptr) result;
+               void *ptr = (void *) (_Unwind_Ptr) result;
                switch (*op_ptr++)
                  {
                  case 1:
@@ -572,12 +598,12 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
              result = ~result;
              break;
            case DW_OP_plus_uconst:
-             op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
-             result += reg;
+             op_ptr = read_uleb128 (op_ptr, &utmp);
+             result += utmp;
              break;
-           /* Avoid warnings.  */
+
            default:
-             break;
+             abort ();
            }
          break;
 
@@ -597,68 +623,68 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
          {
            /* Binary operations.  */
            _Unwind_Word first, second;
-         if ((stack_elt -= 2) < 0)
-           abort ();
-         second = stack[stack_elt];
-         first = stack[stack_elt + 1];
+           if ((stack_elt -= 2) < 0)
+             abort ();
+           second = stack[stack_elt];
+           first = stack[stack_elt + 1];
 
-         switch (op)
-           {
-           case DW_OP_and:
-             result = second & first;
-             break;
-           case DW_OP_div:
-             result = (_Unwind_Sword)second / (_Unwind_Sword)first;
-             break;
-           case DW_OP_minus:
-             result = second - first;
-             break;
-           case DW_OP_mod:
-             result = (_Unwind_Sword)second % (_Unwind_Sword)first;
-             break;
-           case DW_OP_mul:
-             result = second * first;
-             break;
-           case DW_OP_or:
-             result = second | first;
-             break;
-           case DW_OP_plus:
-             result = second + first;
-             break;
-           case DW_OP_shl:
-             result = second << first;
-             break;
-           case DW_OP_shr:
-             result = second >> first;
-             break;
-           case DW_OP_shra:
-             result = (_Unwind_Sword)second >> first;
-             break;
-           case DW_OP_xor:
-             result = second ^ first;
-             break;
-           case DW_OP_le:
-             result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
-             break;
-           case DW_OP_ge:
-             result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
-             break;
-           case DW_OP_eq:
-             result = (_Unwind_Sword)first == (_Unwind_Sword)second;
-             break;
-           case DW_OP_lt:
-             result = (_Unwind_Sword)first < (_Unwind_Sword)second;
-             break;
-           case DW_OP_gt:
-             result = (_Unwind_Sword)first > (_Unwind_Sword)second;
-             break;
-           case DW_OP_ne:
-             result = (_Unwind_Sword)first != (_Unwind_Sword)second;
-             break;
-           default:
-             /* Avoid warnings.  */
-             break;
-           }
+           switch (op)
+             {
+             case DW_OP_and:
+               result = second & first;
+               break;
+             case DW_OP_div:
+               result = (_Unwind_Sword) second / (_Unwind_Sword) first;
+               break;
+             case DW_OP_minus:
+               result = second - first;
+               break;
+             case DW_OP_mod:
+               result = (_Unwind_Sword) second % (_Unwind_Sword) first;
+               break;
+             case DW_OP_mul:
+               result = second * first;
+               break;
+             case DW_OP_or:
+               result = second | first;
+               break;
+             case DW_OP_plus:
+               result = second + first;
+               break;
+             case DW_OP_shl:
+               result = second << first;
+               break;
+             case DW_OP_shr:
+               result = second >> first;
+               break;
+             case DW_OP_shra:
+               result = (_Unwind_Sword) second >> first;
+               break;
+             case DW_OP_xor:
+               result = second ^ first;
+               break;
+             case DW_OP_le:
+               result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
+               break;
+             case DW_OP_ge:
+               result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
+               break;
+             case DW_OP_eq:
+               result = (_Unwind_Sword) first == (_Unwind_Sword) second;
+               break;
+             case DW_OP_lt:
+               result = (_Unwind_Sword) first < (_Unwind_Sword) second;
+               break;
+             case DW_OP_gt:
+               result = (_Unwind_Sword) first > (_Unwind_Sword) second;
+               break;
+             case DW_OP_ne:
+               result = (_Unwind_Sword) first != (_Unwind_Sword) second;
+               break;
+
+             default:
+               abort ();
+             }
          }
          break;
 
@@ -714,20 +740,26 @@ execute_cfa_program (const unsigned char *insn_ptr,
   /* Don't allow remember/restore between CIE and FDE programs.  */
   fs->regs.prev = NULL;
 
+  /* The comparison with the return address uses < rather than <= because
+     we are only interested in the effects of code before the call; for a
+     noreturn function, the return address may point to unrelated code with
+     a different stack configuration that we are not interested in.  We
+     assume that the call itself is unwind info-neutral; if not, or if
+     there are delay instructions that adjust the stack, these must be
+     reflected at the point immediately before the call insn.  */
   while (insn_ptr < insn_end && fs->pc < context->ra)
     {
       unsigned char insn = *insn_ptr++;
-      _Unwind_Word reg;
-      _Unwind_Sword offset;
-      _Unwind_Ptr ptrtmp;
+      _Unwind_Word reg, utmp;
+      _Unwind_Sword offset, stmp;
 
       if ((insn & 0xc0) == DW_CFA_advance_loc)
        fs->pc += (insn & 0x3f) * fs->code_align;
       else if ((insn & 0xc0) == DW_CFA_offset)
        {
          reg = insn & 0x3f;
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         offset = ptrtmp * fs->data_align;
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
+         offset = (_Unwind_Sword) utmp * fs->data_align;
          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
          fs->regs.reg[reg].loc.offset = offset;
        }
@@ -757,28 +789,31 @@ execute_cfa_program (const unsigned char *insn_ptr,
          break;
 
        case DW_CFA_offset_extended:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         offset = ptrtmp * fs->data_align;
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
+         offset = (_Unwind_Sword) utmp * fs->data_align;
          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
          fs->regs.reg[reg].loc.offset = offset;
          break;
 
        case DW_CFA_restore_extended:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
          fs->regs.reg[reg].how = REG_UNSAVED;
          break;
 
        case DW_CFA_undefined:
        case DW_CFA_same_value:
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
+         break;
+
        case DW_CFA_nop:
          break;
 
        case DW_CFA_register:
          {
            _Unwind_Word reg2;
-           insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
-           insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
+           insn_ptr = read_uleb128 (insn_ptr, &reg);
+           insn_ptr = read_uleb128 (insn_ptr, &reg2);
            fs->regs.reg[reg].how = REG_SAVED_REG;
            fs->regs.reg[reg].loc.reg = reg2;
          }
@@ -793,7 +828,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
                unused_rs = unused_rs->prev;
              }
            else
-             new_rs = alloca (sizeof (struct frame_state_reg_info));
+             new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
 
            *new_rs = fs->regs;
            fs->regs.prev = new_rs;
@@ -810,60 +845,55 @@ execute_cfa_program (const unsigned char *insn_ptr,
          break;
 
        case DW_CFA_def_cfa:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_reg = ptrtmp;
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_offset = ptrtmp;
+         insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
+         fs->cfa_offset = utmp;
          fs->cfa_how = CFA_REG_OFFSET;
          break;
 
        case DW_CFA_def_cfa_register:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_reg = ptrtmp;
+         insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
          fs->cfa_how = CFA_REG_OFFSET;
          break;
 
        case DW_CFA_def_cfa_offset:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_offset = ptrtmp;
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
+         fs->cfa_offset = utmp;
          /* cfa_how deliberately not set.  */
          break;
 
        case DW_CFA_def_cfa_expression:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
          fs->cfa_exp = insn_ptr;
          fs->cfa_how = CFA_EXP;
-         insn_ptr += ptrtmp;
+         insn_ptr += utmp;
          break;
 
        case DW_CFA_expression:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
          fs->regs.reg[reg].how = REG_SAVED_EXP;
          fs->regs.reg[reg].loc.exp = insn_ptr;
-         insn_ptr += ptrtmp;
+         insn_ptr += utmp;
          break;
 
          /* From the 2.1 draft.  */
        case DW_CFA_offset_extended_sf:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
-         insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
-         offset = (saddr)ptrtmp * fs->data_align;
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
+         insn_ptr = read_sleb128 (insn_ptr, &stmp);
+         offset = stmp * fs->data_align;
          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
          fs->regs.reg[reg].loc.offset = offset;
          break;
 
        case DW_CFA_def_cfa_sf:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_reg = ptrtmp;
-         insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_offset = (saddr)ptrtmp;
+         insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+         insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
          fs->cfa_how = CFA_REG_OFFSET;
          break;
 
        case DW_CFA_def_cfa_offset_sf:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         fs->cfa_offset = ptrtmp;
+         insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
          /* cfa_how deliberately not set.  */
          break;
 
@@ -877,16 +907,15 @@ execute_cfa_program (const unsigned char *insn_ptr,
          break;
 
        case DW_CFA_GNU_args_size:
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         context->args_size = ptrtmp;
+         insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
          break;
 
        case DW_CFA_GNU_negative_offset_extended:
          /* Obsoleted by DW_CFA_offset_extended_sf, but used by
             older PowerPC code.  */
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
-         insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
-         offset = ptrtmp * fs->data_align;
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
+         insn_ptr = read_uleb128 (insn_ptr, &utmp);
+         offset = (_Unwind_Word) utmp * fs->data_align;
          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
          fs->regs.reg[reg].loc.offset = -offset;
          break;
@@ -897,6 +926,11 @@ execute_cfa_program (const unsigned char *insn_ptr,
     }
 }
 \f
+/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
+   its caller and decode it into FS.  This function also sets the
+   args_size and lsda members of CONTEXT, as they are really information
+   about the caller's frame.  */
+
 static _Unwind_Reason_Code
 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
 {
@@ -913,7 +947,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
     {
       /* Couldn't find frame unwind info for this function.  Try a
         target-specific fallback mechanism.  This will necessarily
-        not profide a personality routine or LSDA.  */
+        not provide a personality routine or LSDA.  */
 #ifdef MD_FALLBACK_FRAME_STATE_FOR
       MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
       return _URC_END_OF_STACK;
@@ -937,12 +971,12 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
   execute_cfa_program (insn, end, context, fs);
 
   /* Locate augmentation for the fde.  */
-  aug = (unsigned char *)fde + sizeof (*fde);
+  aug = (unsigned char *) fde + sizeof (*fde);
   aug += 2 * size_of_encoded_value (fs->fde_encoding);
   insn = NULL;
   if (fs->saw_z)
     {
-      _Unwind_Ptr i;
+      _Unwind_Word i;
       aug = read_uleb128 (aug, &i);
       insn = aug + i;
     }
@@ -965,10 +999,10 @@ typedef struct frame_state
   void *eh_ptr;
   long cfa_offset;
   long args_size;
-  long reg_or_offset[DWARF_FRAME_REGISTERS+1];
+  long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
   unsigned short cfa_reg;
   unsigned short retaddr_column;
-  char saved[DWARF_FRAME_REGISTERS+1];
+  char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
 } frame_state;
 
 #ifndef STATIC
@@ -1001,7 +1035,7 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
   if (fs.cfa_how == CFA_EXP)
     return 0;
 
-  for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++)
+  for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
     {
       state_in->saved[reg] = fs.regs.reg[reg].how;
       switch (state_in->saved[reg])
@@ -1059,7 +1093,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
         that this will not be a problem.  */
       {
        const unsigned char *exp = fs->cfa_exp;
-       _Unwind_Ptr len;
+       _Unwind_Word len;
 
        exp = read_uleb128 (exp, &len);
        cfa = (void *) (_Unwind_Ptr)
@@ -1087,7 +1121,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
       case REG_SAVED_EXP:
        {
          const unsigned char *exp = fs->regs.reg[i].loc.exp;
-         _Unwind_Ptr len;
+         _Unwind_Word len;
          _Unwind_Ptr val;
 
          exp = read_uleb128 (exp, &len);
@@ -1099,6 +1133,11 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
       }
 }
 
+/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
+   of its caller.  Update CONTEXT to refer to the caller as well.  Note
+   that the args_size and lsda members are not updated here, but later in
+   uw_frame_state_for.  */
+
 static void
 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
 {
@@ -1113,14 +1152,16 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
    level will be the return address and the CFA.  */
 
-#define uw_init_context(CONTEXT)                                       \
-do {                                                                   \
-  /* Do any necessary initialization to access arbitrary stack frames. \
-     On the SPARC, this means flushing the register windows.  */       \
-  __builtin_unwind_init ();                                            \
-  uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                  \
-                    __builtin_return_address (0));                     \
-} while (0)
+#define uw_init_context(CONTEXT)                                          \
+  do                                                                      \
+    {                                                                     \
+      /* Do any necessary initialization to access arbitrary stack frames. \
+        On the SPARC, this means flushing the register windows.  */       \
+      __builtin_unwind_init ();                                                   \
+      uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                 \
+                        __builtin_return_address (0));                    \
+    }                                                                     \
+  while (0)
 
 static void
 uw_init_context_1 (struct _Unwind_Context *context,
@@ -1154,12 +1195,14 @@ uw_init_context_1 (struct _Unwind_Context *context,
    macro because __builtin_eh_return must be invoked in the context of
    our caller.  */
 
-#define uw_install_context(CURRENT, TARGET)                            \
-do {                                                                   \
-  long offset = uw_install_context_1 ((CURRENT), (TARGET));            \
-  void *handler = __builtin_frob_return_addr ((TARGET)->ra);           \
-  __builtin_eh_return (offset, handler);                               \
-} while (0)
+#define uw_install_context(CURRENT, TARGET)                             \
+  do                                                                    \
+    {                                                                   \
+      long offset = uw_install_context_1 ((CURRENT), (TARGET));                 \
+      void *handler = __builtin_frob_return_addr ((TARGET)->ra);        \
+      __builtin_eh_return (offset, handler);                            \
+    }                                                                   \
+  while (0)
 
 static inline void
 init_dwarf_reg_size_table (void)
index 9a031c1f32edb979c80d81a02d36eaa0ebcdcb5b..f7873928819c0c4d19d29291bb326caee7801f7a 100644 (file)
@@ -1,28 +1,28 @@
 /* Exception handling and frame unwind runtime interface routines.
    Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
-   This file is part of GNU CC.
+   This file is part of GCC.
 
-   GNU CC is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.
 
-   GNU CC is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GNU CC; see the file COPYING.  If not, write to
-   the Free Software Foundation, 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 /* @@@ Really this should be out of line, but this also causes link
    compatibility problems with the base ABI.  This is slightly better
    than duplicating code, however.  */
 
-/* If using C++, references to abort have to be qualified with std::. */
+/* If using C++, references to abort have to be qualified with std::.  */
 #if __cplusplus
 #define __gxx_abort std::abort
 #else
@@ -66,10 +66,7 @@ extern const unsigned char *read_encoded_value_with_base
    This is only defined for fixed-size encodings, and so does not
    include leb128.  */
 
-#ifndef _LIBC
-static
-#endif
-unsigned int
+static unsigned int
 size_of_encoded_value (unsigned char encoding)
 #if defined(_LIBC) && !defined(NO_BASE_OF_ENCODED_VALUE)
 ;
@@ -125,14 +122,62 @@ base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
 
 #endif
 
+/* Read an unsigned leb128 value from P, store the value in VAL, return
+   P incremented past the value.  We assume that a word is large enough to
+   hold any value so encoded; if it is smaller than a pointer on some target,
+   pointers should not be leb128 encoded on that target.  */
+
+static const unsigned char *
+read_uleb128 (const unsigned char *p, _Unwind_Word *val)
+{
+  unsigned int shift = 0;
+  unsigned char byte;
+  _Unwind_Word result;
+
+  result = 0;
+  do
+    {
+      byte = *p++;
+      result |= (byte & 0x7f) << shift;
+      shift += 7;
+    }
+  while (byte & 0x80);
+
+  *val = result;
+  return p;
+}
+
+/* Similar, but read a signed leb128 value.  */
+
+static const unsigned char *
+read_sleb128 (const unsigned char *p, _Unwind_Sword *val)
+{
+  unsigned int shift = 0;
+  unsigned char byte;
+  _Unwind_Word result;
+
+  result = 0;
+  do
+    {
+      byte = *p++;
+      result |= (byte & 0x7f) << shift;
+      shift += 7;
+    }
+  while (byte & 0x80);
+
+  /* Sign-extend a negative value.  */
+  if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
+    result |= -(1L << shift);
+
+  *val = (_Unwind_Sword) result;
+  return p;
+}
+
 /* Load an encoded value from memory at P.  The value is returned in VAL;
    The function returns P incremented past the value.  BASE is as given
    by base_of_encoded_value for this encoding in the appropriate context.  */
 
-#ifndef _LIBC
-static
-#endif
-const unsigned char *
+static const unsigned char *
 read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
                              const unsigned char *p, _Unwind_Ptr *val)
 #if defined(_LIBC) && !defined(NO_BASE_OF_ENCODED_VALUE)
@@ -151,56 +196,37 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
     } __attribute__((__packed__));
 
   union unaligned *u = (union unaligned *) p;
-  _Unwind_Ptr result;
+  _Unwind_Internal_Ptr result;
 
   if (encoding == DW_EH_PE_aligned)
     {
-      _Unwind_Ptr a = (_Unwind_Ptr)p;
+      _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
       a = (a + sizeof (void *) - 1) & - sizeof(void *);
-      result = *(_Unwind_Ptr *) a;
-      p = (const unsigned char *)(a + sizeof (void *));
+      result = *(_Unwind_Internal_Ptr *) a;
+      p = (const unsigned char *) (a + sizeof (void *));
     }
   else
     {
       switch (encoding & 0x0f)
        {
        case DW_EH_PE_absptr:
-         result = (_Unwind_Ptr) u->ptr;
+         result = (_Unwind_Internal_Ptr) u->ptr;
          p += sizeof (void *);
          break;
 
        case DW_EH_PE_uleb128:
          {
-           unsigned int shift = 0;
-           unsigned char byte;
-
-           result = 0;
-           do
-             {
-               byte = *p++;
-               result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
-               shift += 7;
-             }
-           while (byte & 0x80);
+           _Unwind_Word tmp;
+           p = read_uleb128 (p, &tmp);
+           result = (_Unwind_Internal_Ptr) tmp;
          }
          break;
 
        case DW_EH_PE_sleb128:
          {
-           unsigned int shift = 0;
-           unsigned char byte;
-
-           result = 0;
-           do
-             {
-               byte = *p++;
-               result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
-               shift += 7;
-             }
-           while (byte & 0x80);
-
-           if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
-             result |= -(1L << shift);
+           _Unwind_Sword tmp;
+           p = read_sleb128 (p, &tmp);
+           result = (_Unwind_Internal_Ptr) tmp;
          }
          break;
 
@@ -237,9 +263,9 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
       if (result != 0)
        {
          result += ((encoding & 0x70) == DW_EH_PE_pcrel
-                    ? (_Unwind_Ptr)u : base);
+                    ? (_Unwind_Internal_Ptr) u : base);
          if (encoding & DW_EH_PE_indirect)
-           result = *(_Unwind_Ptr *)result;
+           result = *(_Unwind_Internal_Ptr *) result;
        }
     }
 
@@ -263,20 +289,3 @@ read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
 }
 
 #endif
-
-/* Read an unsigned leb128 value from P, store the value in VAL, return
-   P incremented past the value.  */
-
-static inline const unsigned char *
-read_uleb128 (const unsigned char *p, _Unwind_Ptr *val)
-{
-  return read_encoded_value_with_base (DW_EH_PE_uleb128, 0, p, val);
-}
-
-/* Similar, but read a signed leb128 value.  */
-
-static inline const unsigned char *
-read_sleb128 (const unsigned char *p, _Unwind_Ptr *val)
-{
-  return read_encoded_value_with_base (DW_EH_PE_sleb128, 0, p, val);
-}
This page took 0.101327 seconds and 5 git commands to generate.