/* Copyright (C) 1997, 1998, 1999, 2000, 2001 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
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. */
+#ifndef _Unwind_Find_FDE
#include "tconfig.h"
#include "tsystem.h"
#include "dwarf2.h"
#include "unwind-pe.h"
#include "unwind-dw2-fde.h"
#include "gthr.h"
+#endif
/* The unseen_objects list contains objects that have been registered
but not yet categorized in any way. The seen_objects list has had
__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)
+ return;
+
ob->pc_begin = (void *)-1;
ob->tbase = tbase;
ob->dbase = dbase;
void
__register_frame (void *begin)
{
- struct object *ob = (struct object *) malloc (sizeof (struct object));
+ struct object *ob;
+
+ /* If .eh_frame is empty, don't register at all. */
+ if (*(uword *) begin == 0)
+ return;
+
+ ob = (struct object *) malloc (sizeof (struct object));
__register_frame_info (begin, ob);
}
struct object **p;
struct object *ob = 0;
+ /* If .eh_frame is empty, we haven't registered. */
+ if (*(uword *) begin == 0)
+ return ob;
+
init_object_mutex_once ();
__gthread_mutex_lock (&object_mutex);
void
__deregister_frame (void *begin)
{
- free (__deregister_frame_info (begin));
+ /* If .eh_frame is empty, we haven't registered. */
+ if (*(uword *) begin != 0)
+ free (__deregister_frame_info (begin));
}
\f
{
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. */
/* 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;
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;
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
probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
probe = chain_end)
{
- chain_end = (fde **)erratic->array[probe - linear->array];
+ chain_end = (fde **) erratic->array[probe - linear->array];
erratic->array[probe - linear->array] = NULL;
}
- erratic->array[i] = (fde *)chain_end;
+ erratic->array[i] = (fde *) chain_end;
chain_end = &linear->array[i];
}
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--;
- }
+ 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);
+ }
+ while (i2 > 0);
v1->count += v2->count;
}
}
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;
if (encoding == DW_EH_PE_absptr)
{
- if (*(_Unwind_Ptr *)this_fde->pc_begin == 0)
+ if (*(_Unwind_Ptr *) this_fde->pc_begin == 0)
continue;
}
else
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;
}
continue;
}
- if ((_Unwind_Ptr)pc - pc_begin < pc_range)
+ if ((_Unwind_Ptr) pc - pc_begin < pc_range)
return this_fde;
}
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;
&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;
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;
__gthread_mutex_lock (&object_mutex);
/* Linear search through the classified objects, to find the one
- containing the pc. Note that pc_begin is sorted decending, and
+ containing the pc. Note that pc_begin is sorted descending, and
we expect objects to be non-overlapping. */
for (ob = seen_objects; ob; ob = ob->next)
if (pc >= ob->pc_begin)