aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/generic/unwind-dw2-fde.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-13 16:45:10 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-13 16:45:10 +0000
commit6180ac2f06eec2a3f2ae05b04af60baf4f1e4149 (patch)
tree3ab6c00f8ad6eaf2f911e90a888a29783b3c0fa5 /sysdeps/generic/unwind-dw2-fde.c
parent6a1aff6912ff551906d4c60f5ca2eeb8fd78090e (diff)
downloadglibc-6180ac2f06eec2a3f2ae05b04af60baf4f1e4149.zip
glibc-6180ac2f06eec2a3f2ae05b04af60baf4f1e4149.tar.gz
glibc-6180ac2f06eec2a3f2ae05b04af60baf4f1e4149.tar.bz2
Update from recent gcc version.
Diffstat (limited to 'sysdeps/generic/unwind-dw2-fde.c')
-rw-r--r--sysdeps/generic/unwind-dw2-fde.c228
1 files changed, 126 insertions, 102 deletions
diff --git a/sysdeps/generic/unwind-dw2-fde.c b/sysdeps/generic/unwind-dw2-fde.c
index 6c51c6f..64c0846 100644
--- a/sysdeps/generic/unwind-dw2-fde.c
+++ b/sysdeps/generic/unwind-dw2-fde.c
@@ -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