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
/* 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)