* Makefile.in (rtlanal.o): Depend on $(TM_P_H).
[official-gcc.git] / gcc / unwind-dw2-fde.c
blob729adbbd4ab7201a7abbdda6141c0b659cb26a80
1 /* Subroutines needed for unwinding stack frames for exception handling. */
2 /* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Jason Merrill <jason@cygnus.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
19 executable.)
21 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22 WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 for more details.
26 You should have received a copy of the GNU General Public License
27 along with GCC; see the file COPYING. If not, write to the Free
28 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
29 02111-1307, USA. */
31 #include "tconfig.h"
32 #include "tsystem.h"
33 #include "dwarf2.h"
34 #include "unwind.h"
35 #define NO_BASE_OF_ENCODED_VALUE
36 #include "unwind-pe.h"
37 #include "unwind-dw2-fde.h"
38 #include "gthr.h"
40 /* The unseen_objects list contains objects that have been registered
41 but not yet categorized in any way. The seen_objects list has had
42 it's pc_begin and count fields initialized at minimum, and is sorted
43 by decreasing value of pc_begin. */
44 static struct object *unseen_objects;
45 static struct object *seen_objects;
47 #ifdef __GTHREAD_MUTEX_INIT
48 static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
49 #else
50 static __gthread_mutex_t object_mutex;
51 #endif
53 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
54 static void
55 init_object_mutex (void)
57 __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
60 static void
61 init_object_mutex_once (void)
63 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
64 __gthread_once (&once, init_object_mutex);
66 #else
67 #define init_object_mutex_once()
68 #endif
70 /* Called from crtbegin.o to register the unwind info for an object. */
72 void
73 __register_frame_info_bases (void *begin, struct object *ob,
74 void *tbase, void *dbase)
76 ob->pc_begin = (void *)-1;
77 ob->tbase = tbase;
78 ob->dbase = dbase;
79 ob->u.single = begin;
80 ob->s.i = 0;
81 ob->s.b.encoding = DW_EH_PE_omit;
83 init_object_mutex_once ();
84 __gthread_mutex_lock (&object_mutex);
86 ob->next = unseen_objects;
87 unseen_objects = ob;
89 __gthread_mutex_unlock (&object_mutex);
92 void
93 __register_frame_info (void *begin, struct object *ob)
95 __register_frame_info_bases (begin, ob, 0, 0);
98 void
99 __register_frame (void *begin)
101 struct object *ob = (struct object *) malloc (sizeof (struct object));
102 __register_frame_info (begin, ob);
105 /* Similar, but BEGIN is actually a pointer to a table of unwind entries
106 for different translation units. Called from the file generated by
107 collect2. */
109 void
110 __register_frame_info_table_bases (void *begin, struct object *ob,
111 void *tbase, void *dbase)
113 ob->pc_begin = (void *)-1;
114 ob->tbase = tbase;
115 ob->dbase = dbase;
116 ob->u.array = begin;
117 ob->s.i = 0;
118 ob->s.b.from_array = 1;
119 ob->s.b.encoding = DW_EH_PE_omit;
121 init_object_mutex_once ();
122 __gthread_mutex_lock (&object_mutex);
124 ob->next = unseen_objects;
125 unseen_objects = ob;
127 __gthread_mutex_unlock (&object_mutex);
130 void
131 __register_frame_info_table (void *begin, struct object *ob)
133 __register_frame_info_table_bases (begin, ob, 0, 0);
136 void
137 __register_frame_table (void *begin)
139 struct object *ob = (struct object *) malloc (sizeof (struct object));
140 __register_frame_info_table (begin, ob);
143 /* Called from crtbegin.o to deregister the unwind info for an object. */
144 /* ??? Glibc has for a while now exported __register_frame_info and
145 __deregister_frame_info. If we call __register_frame_info_bases
146 from crtbegin (wherein it is declared weak), and this object does
147 not get pulled from libgcc.a for other reasons, then the
148 invocation of __deregister_frame_info will be resolved from glibc.
149 Since the registration did not happen there, we'll abort.
151 Therefore, declare a new deregistration entry point that does the
152 exact same thing, but will resolve to the same library as
153 implements __register_frame_info_bases. */
155 void *
156 __deregister_frame_info_bases (void *begin)
158 struct object **p;
159 struct object *ob = 0;
161 init_object_mutex_once ();
162 __gthread_mutex_lock (&object_mutex);
164 for (p = &unseen_objects; *p ; p = &(*p)->next)
165 if ((*p)->u.single == begin)
167 ob = *p;
168 *p = ob->next;
169 goto out;
172 for (p = &seen_objects; *p ; p = &(*p)->next)
173 if ((*p)->s.b.sorted)
175 if ((*p)->u.sort->orig_data == begin)
177 ob = *p;
178 *p = ob->next;
179 free (ob->u.sort);
180 goto out;
183 else
185 if ((*p)->u.single == begin)
187 ob = *p;
188 *p = ob->next;
189 goto out;
193 __gthread_mutex_unlock (&object_mutex);
194 abort ();
196 out:
197 __gthread_mutex_unlock (&object_mutex);
198 return (void *) ob;
201 void *
202 __deregister_frame_info (void *begin)
204 return __deregister_frame_info_bases (begin);
207 void
208 __deregister_frame (void *begin)
210 free (__deregister_frame_info (begin));
214 /* Like base_of_encoded_value, but take the base from a struct object
215 instead of an _Unwind_Context. */
217 static _Unwind_Ptr
218 base_from_object (unsigned char encoding, struct object *ob)
220 if (encoding == DW_EH_PE_omit)
221 return 0;
223 switch (encoding & 0x70)
225 case DW_EH_PE_absptr:
226 case DW_EH_PE_pcrel:
227 case DW_EH_PE_aligned:
228 return 0;
230 case DW_EH_PE_textrel:
231 return (_Unwind_Ptr) ob->tbase;
232 case DW_EH_PE_datarel:
233 return (_Unwind_Ptr) ob->dbase;
235 abort ();
238 /* Return the FDE pointer encoding from the CIE. */
239 /* ??? This is a subset of extract_cie_info from unwind-dw2.c. */
241 static int
242 get_cie_encoding (struct dwarf_cie *cie)
244 const unsigned char *aug, *p;
245 _Unwind_Ptr dummy;
246 _Unwind_Word utmp;
247 _Unwind_Sword stmp;
249 aug = cie->augmentation;
250 if (aug[0] != 'z')
251 return DW_EH_PE_absptr;
253 p = aug + strlen (aug) + 1; /* Skip the augmentation string. */
254 p = read_uleb128 (p, &utmp); /* Skip code alignment. */
255 p = read_sleb128 (p, &stmp); /* Skip data alignment. */
256 p++; /* Skip return address column. */
258 aug++; /* Skip 'z' */
259 p = read_uleb128 (p, &utmp); /* Skip augmentation length. */
260 while (1)
262 /* This is what we're looking for. */
263 if (*aug == 'R')
264 return *p;
265 /* Personality encoding and pointer. */
266 else if (*aug == 'P')
268 /* ??? Avoid dereferencing indirect pointers, since we're
269 faking the base address. Gotta keep DW_EH_PE_aligned
270 intact, however. */
271 p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
273 /* LSDA encoding. */
274 else if (*aug == 'L')
275 p++;
276 /* Otherwise end of string, or unknown augmentation. */
277 else
278 return DW_EH_PE_absptr;
279 aug++;
283 static inline int
284 get_fde_encoding (struct dwarf_fde *f)
286 return get_cie_encoding (get_cie (f));
290 /* Sorting an array of FDEs by address.
291 (Ideally we would have the linker sort the FDEs so we don't have to do
292 it at run time. But the linkers are not yet prepared for this.) */
294 /* Comparison routines. Three variants of increasing complexity. */
296 static int
297 fde_unencoded_compare (struct object *ob __attribute__((unused)),
298 fde *x, fde *y)
300 if (x->pc_begin > y->pc_begin)
301 return 1;
302 if (x->pc_begin < y->pc_begin)
303 return -1;
304 return 0;
307 static int
308 fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
310 _Unwind_Ptr base, x_ptr, y_ptr;
312 base = base_from_object (ob->s.b.encoding, ob);
313 read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
314 read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
316 if (x_ptr > y_ptr)
317 return 1;
318 if (x_ptr < y_ptr)
319 return -1;
320 return 0;
323 static int
324 fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
326 int x_encoding, y_encoding;
327 _Unwind_Ptr x_ptr, y_ptr;
329 x_encoding = get_fde_encoding (x);
330 read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
331 x->pc_begin, &x_ptr);
333 y_encoding = get_fde_encoding (y);
334 read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
335 y->pc_begin, &y_ptr);
337 if (x_ptr > y_ptr)
338 return 1;
339 if (x_ptr < y_ptr)
340 return -1;
341 return 0;
344 typedef int (*fde_compare_t) (struct object *, fde *, fde *);
347 /* This is a special mix of insertion sort and heap sort, optimized for
348 the data sets that actually occur. They look like
349 101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130.
350 I.e. a linearly increasing sequence (coming from functions in the text
351 section), with additionally a few unordered elements (coming from functions
352 in gnu_linkonce sections) whose values are higher than the values in the
353 surrounding linear sequence (but not necessarily higher than the values
354 at the end of the linear sequence!).
355 The worst-case total run time is O(N) + O(n log (n)), where N is the
356 total number of FDEs and n is the number of erratic ones. */
358 struct fde_accumulator
360 struct fde_vector *linear;
361 struct fde_vector *erratic;
364 static inline int
365 start_fde_sort (struct fde_accumulator *accu, size_t count)
367 size_t size;
368 if (! count)
369 return 0;
371 size = sizeof (struct fde_vector) + sizeof (fde *) * count;
372 if ((accu->linear = (struct fde_vector *) malloc (size)))
374 accu->linear->count = 0;
375 if ((accu->erratic = (struct fde_vector *) malloc (size)))
376 accu->erratic->count = 0;
377 return 1;
379 else
380 return 0;
383 static inline void
384 fde_insert (struct fde_accumulator *accu, fde *this_fde)
386 if (accu->linear)
387 accu->linear->array[accu->linear->count++] = this_fde;
390 /* Split LINEAR into a linear sequence with low values and an erratic
391 sequence with high values, put the linear one (of longest possible
392 length) into LINEAR and the erratic one into ERRATIC. This is O(N).
394 Because the longest linear sequence we are trying to locate within the
395 incoming LINEAR array can be interspersed with (high valued) erratic
396 entries. We construct a chain indicating the sequenced entries.
397 To avoid having to allocate this chain, we overlay it onto the space of
398 the ERRATIC array during construction. A final pass iterates over the
399 chain to determine what should be placed in the ERRATIC array, and
400 what is the linear sequence. This overlay is safe from aliasing. */
402 static inline void
403 fde_split (struct object *ob, fde_compare_t fde_compare,
404 struct fde_vector *linear, struct fde_vector *erratic)
406 static fde *marker;
407 size_t count = linear->count;
408 fde **chain_end = &marker;
409 size_t i, j, k;
411 /* This should optimize out, but it is wise to make sure this assumption
412 is correct. Should these have different sizes, we cannot cast between
413 them and the overlaying onto ERRATIC will not work. */
414 if (sizeof (fde *) != sizeof (fde **))
415 abort ();
417 for (i = 0; i < count; i++)
419 fde **probe;
421 for (probe = chain_end;
422 probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
423 probe = chain_end)
425 chain_end = (fde **)erratic->array[probe - linear->array];
426 erratic->array[probe - linear->array] = NULL;
428 erratic->array[i] = (fde *)chain_end;
429 chain_end = &linear->array[i];
432 /* Each entry in LINEAR which is part of the linear sequence we have
433 discovered will correspond to a non-NULL entry in the chain we built in
434 the ERRATIC array. */
435 for (i = j = k = 0; i < count; i++)
436 if (erratic->array[i])
437 linear->array[j++] = linear->array[i];
438 else
439 erratic->array[k++] = linear->array[i];
440 linear->count = j;
441 erratic->count = k;
444 /* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must
445 use a name that does not conflict. */
447 static void
448 frame_heapsort (struct object *ob, fde_compare_t fde_compare,
449 struct fde_vector *erratic)
451 /* For a description of this algorithm, see:
452 Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
453 p. 60-61. */
454 fde ** a = erratic->array;
455 /* A portion of the array is called a "heap" if for all i>=0:
456 If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
457 If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
458 #define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
459 size_t n = erratic->count;
460 size_t m = n;
461 size_t i;
463 while (m > 0)
465 /* Invariant: a[m..n-1] is a heap. */
466 m--;
467 for (i = m; 2*i+1 < n; )
469 if (2*i+2 < n
470 && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
471 && fde_compare (ob, a[2*i+2], a[i]) > 0)
473 SWAP (a[i], a[2*i+2]);
474 i = 2*i+2;
476 else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
478 SWAP (a[i], a[2*i+1]);
479 i = 2*i+1;
481 else
482 break;
485 while (n > 1)
487 /* Invariant: a[0..n-1] is a heap. */
488 n--;
489 SWAP (a[0], a[n]);
490 for (i = 0; 2*i+1 < n; )
492 if (2*i+2 < n
493 && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
494 && fde_compare (ob, a[2*i+2], a[i]) > 0)
496 SWAP (a[i], a[2*i+2]);
497 i = 2*i+2;
499 else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
501 SWAP (a[i], a[2*i+1]);
502 i = 2*i+1;
504 else
505 break;
508 #undef SWAP
511 /* Merge V1 and V2, both sorted, and put the result into V1. */
512 static inline void
513 fde_merge (struct object *ob, fde_compare_t fde_compare,
514 struct fde_vector *v1, struct fde_vector *v2)
516 size_t i1, i2;
517 fde * fde2;
519 i2 = v2->count;
520 if (i2 > 0)
522 i1 = v1->count;
523 do {
524 i2--;
525 fde2 = v2->array[i2];
526 while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
528 v1->array[i1+i2] = v1->array[i1-1];
529 i1--;
531 v1->array[i1+i2] = fde2;
532 } while (i2 > 0);
533 v1->count += v2->count;
537 static inline void
538 end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
540 fde_compare_t fde_compare;
542 if (accu->linear && accu->linear->count != count)
543 abort ();
545 if (ob->s.b.mixed_encoding)
546 fde_compare = fde_mixed_encoding_compare;
547 else if (ob->s.b.encoding == DW_EH_PE_absptr)
548 fde_compare = fde_unencoded_compare;
549 else
550 fde_compare = fde_single_encoding_compare;
552 if (accu->erratic)
554 fde_split (ob, fde_compare, accu->linear, accu->erratic);
555 if (accu->linear->count + accu->erratic->count != count)
556 abort ();
557 frame_heapsort (ob, fde_compare, accu->erratic);
558 fde_merge (ob, fde_compare, accu->linear, accu->erratic);
559 free (accu->erratic);
561 else
563 /* We've not managed to malloc an erratic array,
564 so heap sort in the linear one. */
565 frame_heapsort (ob, fde_compare, accu->linear);
570 /* Update encoding, mixed_encoding, and pc_begin for OB for the
571 fde array beginning at THIS_FDE. Return the number of fdes
572 encountered along the way. */
574 static size_t
575 classify_object_over_fdes (struct object *ob, fde *this_fde)
577 struct dwarf_cie *last_cie = 0;
578 size_t count = 0;
579 int encoding = DW_EH_PE_absptr;
580 _Unwind_Ptr base = 0;
582 for (; this_fde->length != 0; this_fde = next_fde (this_fde))
584 struct dwarf_cie *this_cie;
585 _Unwind_Ptr mask, pc_begin;
587 /* Skip CIEs. */
588 if (this_fde->CIE_delta == 0)
589 continue;
591 /* Determine the encoding for this FDE. Note mixed encoded
592 objects for later. */
593 this_cie = get_cie (this_fde);
594 if (this_cie != last_cie)
596 last_cie = this_cie;
597 encoding = get_cie_encoding (this_cie);
598 base = base_from_object (encoding, ob);
599 if (ob->s.b.encoding == DW_EH_PE_omit)
600 ob->s.b.encoding = encoding;
601 else if (ob->s.b.encoding != encoding)
602 ob->s.b.mixed_encoding = 1;
605 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
606 &pc_begin);
608 /* Take care to ignore link-once functions that were removed.
609 In these cases, the function address will be NULL, but if
610 the encoding is smaller than a pointer a true NULL may not
611 be representable. Assume 0 in the representable bits is NULL. */
612 mask = size_of_encoded_value (encoding);
613 if (mask < sizeof (void *))
614 mask = (1L << (mask << 3)) - 1;
615 else
616 mask = -1;
618 if ((pc_begin & mask) == 0)
619 continue;
621 count += 1;
622 if ((void *)pc_begin < ob->pc_begin)
623 ob->pc_begin = (void *)pc_begin;
626 return count;
629 static void
630 add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
632 struct dwarf_cie *last_cie = 0;
633 int encoding = ob->s.b.encoding;
634 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
636 for (; this_fde->length != 0; this_fde = next_fde (this_fde))
638 struct dwarf_cie *this_cie;
640 /* Skip CIEs. */
641 if (this_fde->CIE_delta == 0)
642 continue;
644 if (ob->s.b.mixed_encoding)
646 /* Determine the encoding for this FDE. Note mixed encoded
647 objects for later. */
648 this_cie = get_cie (this_fde);
649 if (this_cie != last_cie)
651 last_cie = this_cie;
652 encoding = get_cie_encoding (this_cie);
653 base = base_from_object (encoding, ob);
657 if (encoding == DW_EH_PE_absptr)
659 if (*(_Unwind_Ptr *)this_fde->pc_begin == 0)
660 continue;
662 else
664 _Unwind_Ptr pc_begin, mask;
666 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
667 &pc_begin);
669 /* Take care to ignore link-once functions that were removed.
670 In these cases, the function address will be NULL, but if
671 the encoding is smaller than a pointer a true NULL may not
672 be representable. Assume 0 in the representable bits is NULL. */
673 mask = size_of_encoded_value (encoding);
674 if (mask < sizeof (void *))
675 mask = (1L << (mask << 3)) - 1;
676 else
677 mask = -1;
679 if ((pc_begin & mask) == 0)
680 continue;
683 fde_insert (accu, this_fde);
687 /* Set up a sorted array of pointers to FDEs for a loaded object. We
688 count up the entries before allocating the array because it's likely to
689 be faster. We can be called multiple times, should we have failed to
690 allocate a sorted fde array on a previous occasion. */
692 static inline void
693 init_object (struct object* ob)
695 struct fde_accumulator accu;
696 size_t count;
698 count = ob->s.b.count;
699 if (count == 0)
701 if (ob->s.b.from_array)
703 fde **p = ob->u.array;
704 for (count = 0; *p; ++p)
705 count += classify_object_over_fdes (ob, *p);
707 else
708 count = classify_object_over_fdes (ob, ob->u.single);
710 /* The count field we have in the main struct object is somewhat
711 limited, but should suffice for virtually all cases. If the
712 counted value doesn't fit, re-write a zero. The worst that
713 happens is that we re-count next time -- admittedly non-trivial
714 in that this implies some 2M fdes, but at least we function. */
715 ob->s.b.count = count;
716 if (ob->s.b.count != count)
717 ob->s.b.count = 0;
720 if (!start_fde_sort (&accu, count))
721 return;
723 if (ob->s.b.from_array)
725 fde **p;
726 for (p = ob->u.array; *p; ++p)
727 add_fdes (ob, &accu, *p);
729 else
730 add_fdes (ob, &accu, ob->u.single);
732 end_fde_sort (ob, &accu, count);
734 /* Save the original fde pointer, since this is the key by which the
735 DSO will deregister the object. */
736 accu.linear->orig_data = ob->u.single;
737 ob->u.sort = accu.linear;
739 ob->s.b.sorted = 1;
742 /* A linear search through a set of FDEs for the given PC. This is
743 used when there was insufficient memory to allocate and sort an
744 array. */
746 static fde *
747 linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
749 struct dwarf_cie *last_cie = 0;
750 int encoding = ob->s.b.encoding;
751 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
753 for (; this_fde->length != 0; this_fde = next_fde (this_fde))
755 struct dwarf_cie *this_cie;
756 _Unwind_Ptr pc_begin, pc_range;
758 /* Skip CIEs. */
759 if (this_fde->CIE_delta == 0)
760 continue;
762 if (ob->s.b.mixed_encoding)
764 /* Determine the encoding for this FDE. Note mixed encoded
765 objects for later. */
766 this_cie = get_cie (this_fde);
767 if (this_cie != last_cie)
769 last_cie = this_cie;
770 encoding = get_cie_encoding (this_cie);
771 base = base_from_object (encoding, ob);
775 if (encoding == DW_EH_PE_absptr)
777 pc_begin = ((_Unwind_Ptr *)this_fde->pc_begin)[0];
778 pc_range = ((_Unwind_Ptr *)this_fde->pc_begin)[1];
779 if (pc_begin == 0)
780 continue;
782 else
784 _Unwind_Ptr mask;
785 const char *p;
787 p = read_encoded_value_with_base (encoding, base,
788 this_fde->pc_begin, &pc_begin);
789 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
791 /* Take care to ignore link-once functions that were removed.
792 In these cases, the function address will be NULL, but if
793 the encoding is smaller than a pointer a true NULL may not
794 be representable. Assume 0 in the representable bits is NULL. */
795 mask = size_of_encoded_value (encoding);
796 if (mask < sizeof (void *))
797 mask = (1L << (mask << 3)) - 1;
798 else
799 mask = -1;
801 if ((pc_begin & mask) == 0)
802 continue;
805 if ((_Unwind_Ptr)pc - pc_begin < pc_range)
806 return this_fde;
809 return NULL;
812 /* Binary search for an FDE containing the given PC. Here are three
813 implementations of increasing complexity. */
815 static inline fde *
816 binary_search_unencoded_fdes (struct object *ob, void *pc)
818 struct fde_vector *vec = ob->u.sort;
819 size_t lo, hi;
821 for (lo = 0, hi = vec->count; lo < hi; )
823 size_t i = (lo + hi) / 2;
824 fde *f = vec->array[i];
825 void *pc_begin;
826 uaddr pc_range;
828 pc_begin = ((void **)f->pc_begin)[0];
829 pc_range = ((uaddr *)f->pc_begin)[1];
831 if (pc < pc_begin)
832 hi = i;
833 else if (pc >= pc_begin + pc_range)
834 lo = i + 1;
835 else
836 return f;
839 return NULL;
842 static inline fde *
843 binary_search_single_encoding_fdes (struct object *ob, void *pc)
845 struct fde_vector *vec = ob->u.sort;
846 int encoding = ob->s.b.encoding;
847 _Unwind_Ptr base = base_from_object (encoding, ob);
848 size_t lo, hi;
850 for (lo = 0, hi = vec->count; lo < hi; )
852 size_t i = (lo + hi) / 2;
853 fde *f = vec->array[i];
854 _Unwind_Ptr pc_begin, pc_range;
855 const char *p;
857 p = read_encoded_value_with_base (encoding, base, f->pc_begin,
858 &pc_begin);
859 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
861 if ((_Unwind_Ptr)pc < pc_begin)
862 hi = i;
863 else if ((_Unwind_Ptr)pc >= pc_begin + pc_range)
864 lo = i + 1;
865 else
866 return f;
869 return NULL;
872 static inline fde *
873 binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
875 struct fde_vector *vec = ob->u.sort;
876 size_t lo, hi;
878 for (lo = 0, hi = vec->count; lo < hi; )
880 size_t i = (lo + hi) / 2;
881 fde *f = vec->array[i];
882 _Unwind_Ptr pc_begin, pc_range;
883 const char *p;
884 int encoding;
886 encoding = get_fde_encoding (f);
887 p = read_encoded_value_with_base (encoding,
888 base_from_object (encoding, ob),
889 f->pc_begin, &pc_begin);
890 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
892 if ((_Unwind_Ptr)pc < pc_begin)
893 hi = i;
894 else if ((_Unwind_Ptr)pc >= pc_begin + pc_range)
895 lo = i + 1;
896 else
897 return f;
900 return NULL;
903 static fde *
904 search_object (struct object* ob, void *pc)
906 /* If the data hasn't been sorted, try to do this now. We may have
907 more memory available than last time we tried. */
908 if (! ob->s.b.sorted)
910 init_object (ob);
912 /* Despite the above comment, the normal reason to get here is
913 that we've not processed this object before. A quick range
914 check is in order. */
915 if (pc < ob->pc_begin)
916 return NULL;
919 if (ob->s.b.sorted)
921 if (ob->s.b.mixed_encoding)
922 return binary_search_mixed_encoding_fdes (ob, pc);
923 else if (ob->s.b.encoding == DW_EH_PE_absptr)
924 return binary_search_unencoded_fdes (ob, pc);
925 else
926 return binary_search_single_encoding_fdes (ob, pc);
928 else
930 /* Long slow labourious linear search, cos we've no memory. */
931 if (ob->s.b.from_array)
933 fde **p;
934 for (p = ob->u.array; *p ; p++)
936 fde *f = linear_search_fdes (ob, *p, pc);
937 if (f)
938 return f;
940 return NULL;
942 else
943 return linear_search_fdes (ob, ob->u.single, pc);
947 fde *
948 _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
950 struct object *ob;
951 fde *f = NULL;
953 init_object_mutex_once ();
954 __gthread_mutex_lock (&object_mutex);
956 /* Linear search through the classified objects, to find the one
957 containing the pc. Note that pc_begin is sorted descending, and
958 we expect objects to be non-overlapping. */
959 for (ob = seen_objects; ob; ob = ob->next)
960 if (pc >= ob->pc_begin)
962 f = search_object (ob, pc);
963 if (f)
964 goto fini;
965 break;
968 /* Classify and search the objects we've not yet processed. */
969 while ((ob = unseen_objects))
971 struct object **p;
973 unseen_objects = ob->next;
974 f = search_object (ob, pc);
976 /* Insert the object into the classified list. */
977 for (p = &seen_objects; *p ; p = &(*p)->next)
978 if ((*p)->pc_begin < ob->pc_begin)
979 break;
980 ob->next = *p;
981 *p = ob;
983 if (f)
984 goto fini;
987 fini:
988 __gthread_mutex_unlock (&object_mutex);
990 if (f)
992 int encoding;
994 bases->tbase = ob->tbase;
995 bases->dbase = ob->dbase;
997 encoding = ob->s.b.encoding;
998 if (ob->s.b.mixed_encoding)
999 encoding = get_fde_encoding (f);
1000 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
1001 f->pc_begin, (_Unwind_Ptr *)&bases->func);
1004 return f;