00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef _Unwind_Find_FDE
00033 #include "tconfig.h"
00034 #include "tsystem.h"
00035 #include "coretypes.h"
00036 #include "tm.h"
00037 #include "dwarf2.h"
00038 #include "unwind.h"
00039 #define NO_BASE_OF_ENCODED_VALUE
00040 #include "unwind-pe.h"
00041 #include "unwind-dw2-fde.h"
00042 #include "gthr.h"
00043 #endif
00044
00045
00046
00047
00048
00049 static struct object *unseen_objects;
00050 static struct object *seen_objects;
00051
00052 #ifdef __GTHREAD_MUTEX_INIT
00053 static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
00054 #else
00055 static __gthread_mutex_t object_mutex;
00056 #endif
00057
00058 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
00059 static void
00060 init_object_mutex (void)
00061 {
00062 __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
00063 }
00064
00065 static void
00066 init_object_mutex_once (void)
00067 {
00068 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
00069 __gthread_once (&once, init_object_mutex);
00070 }
00071 #else
00072 #define init_object_mutex_once()
00073 #endif
00074
00075
00076
00077 void
00078 __register_frame_info_bases (const void *begin, struct object *ob,
00079 void *tbase, void *dbase)
00080 {
00081
00082 if ((uword *) begin == 0 || *(uword *) begin == 0)
00083 return;
00084
00085 ob->pc_begin = (void *)-1;
00086 ob->tbase = tbase;
00087 ob->dbase = dbase;
00088 ob->u.single = begin;
00089 ob->s.i = 0;
00090 ob->s.b.encoding = DW_EH_PE_omit;
00091 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
00092 ob->fde_end = NULL;
00093 #endif
00094
00095 init_object_mutex_once ();
00096 __gthread_mutex_lock (&object_mutex);
00097
00098 ob->next = unseen_objects;
00099 unseen_objects = ob;
00100
00101 __gthread_mutex_unlock (&object_mutex);
00102 }
00103
00104 void
00105 __register_frame_info (const void *begin, struct object *ob)
00106 {
00107 __register_frame_info_bases (begin, ob, 0, 0);
00108 }
00109
00110 void
00111 __register_frame (void *begin)
00112 {
00113 struct object *ob;
00114
00115
00116 if (*(uword *) begin == 0)
00117 return;
00118
00119 ob = malloc (sizeof (struct object));
00120 __register_frame_info (begin, ob);
00121 }
00122
00123
00124
00125
00126
00127 void
00128 __register_frame_info_table_bases (void *begin, struct object *ob,
00129 void *tbase, void *dbase)
00130 {
00131 ob->pc_begin = (void *)-1;
00132 ob->tbase = tbase;
00133 ob->dbase = dbase;
00134 ob->u.array = begin;
00135 ob->s.i = 0;
00136 ob->s.b.from_array = 1;
00137 ob->s.b.encoding = DW_EH_PE_omit;
00138
00139 init_object_mutex_once ();
00140 __gthread_mutex_lock (&object_mutex);
00141
00142 ob->next = unseen_objects;
00143 unseen_objects = ob;
00144
00145 __gthread_mutex_unlock (&object_mutex);
00146 }
00147
00148 void
00149 __register_frame_info_table (void *begin, struct object *ob)
00150 {
00151 __register_frame_info_table_bases (begin, ob, 0, 0);
00152 }
00153
00154 void
00155 __register_frame_table (void *begin)
00156 {
00157 struct object *ob = malloc (sizeof (struct object));
00158 __register_frame_info_table (begin, ob);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 void *
00174 __deregister_frame_info_bases (const void *begin)
00175 {
00176 struct object **p;
00177 struct object *ob = 0;
00178
00179
00180 if ((uword *) begin == 0 || *(uword *) begin == 0)
00181 return ob;
00182
00183 init_object_mutex_once ();
00184 __gthread_mutex_lock (&object_mutex);
00185
00186 for (p = &unseen_objects; *p ; p = &(*p)->next)
00187 if ((*p)->u.single == begin)
00188 {
00189 ob = *p;
00190 *p = ob->next;
00191 goto out;
00192 }
00193
00194 for (p = &seen_objects; *p ; p = &(*p)->next)
00195 if ((*p)->s.b.sorted)
00196 {
00197 if ((*p)->u.sort->orig_data == begin)
00198 {
00199 ob = *p;
00200 *p = ob->next;
00201 free (ob->u.sort);
00202 goto out;
00203 }
00204 }
00205 else
00206 {
00207 if ((*p)->u.single == begin)
00208 {
00209 ob = *p;
00210 *p = ob->next;
00211 goto out;
00212 }
00213 }
00214
00215 out:
00216 __gthread_mutex_unlock (&object_mutex);
00217 gcc_assert (ob);
00218 return (void *) ob;
00219 }
00220
00221 void *
00222 __deregister_frame_info (const void *begin)
00223 {
00224 return __deregister_frame_info_bases (begin);
00225 }
00226
00227 void
00228 __deregister_frame (void *begin)
00229 {
00230
00231 if (*(uword *) begin != 0)
00232 free (__deregister_frame_info (begin));
00233 }
00234
00235
00236
00237
00238
00239 static _Unwind_Ptr
00240 base_from_object (unsigned char encoding, struct object *ob)
00241 {
00242 if (encoding == DW_EH_PE_omit)
00243 return 0;
00244
00245 switch (encoding & 0x70)
00246 {
00247 case DW_EH_PE_absptr:
00248 case DW_EH_PE_pcrel:
00249 case DW_EH_PE_aligned:
00250 return 0;
00251
00252 case DW_EH_PE_textrel:
00253 return (_Unwind_Ptr) ob->tbase;
00254 case DW_EH_PE_datarel:
00255 return (_Unwind_Ptr) ob->dbase;
00256 default:
00257 gcc_unreachable ();
00258 }
00259 }
00260
00261
00262
00263
00264 static int
00265 get_cie_encoding (const struct dwarf_cie *cie)
00266 {
00267 const unsigned char *aug, *p;
00268 _Unwind_Ptr dummy;
00269 _Unwind_Word utmp;
00270 _Unwind_Sword stmp;
00271
00272 aug = cie->augmentation;
00273 if (aug[0] != 'z')
00274 return DW_EH_PE_absptr;
00275
00276 p = aug + strlen ((const char *)aug) + 1;
00277 p = read_uleb128 (p, &utmp);
00278 p = read_sleb128 (p, &stmp);
00279 if (cie->version == 1)
00280 p++;
00281 else
00282 p = read_uleb128 (p, &utmp);
00283
00284 aug++;
00285 p = read_uleb128 (p, &utmp);
00286 while (1)
00287 {
00288
00289 if (*aug == 'R')
00290 return *p;
00291
00292 else if (*aug == 'P')
00293 {
00294
00295
00296
00297 p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
00298 }
00299
00300 else if (*aug == 'L')
00301 p++;
00302
00303 else
00304 return DW_EH_PE_absptr;
00305 aug++;
00306 }
00307 }
00308
00309 static inline int
00310 get_fde_encoding (const struct dwarf_fde *f)
00311 {
00312 return get_cie_encoding (get_cie (f));
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322 static int
00323 fde_unencoded_compare (struct object *ob __attribute__((unused)),
00324 const fde *x, const fde *y)
00325 {
00326 _Unwind_Ptr x_ptr = *(_Unwind_Ptr *) x->pc_begin;
00327 _Unwind_Ptr y_ptr = *(_Unwind_Ptr *) y->pc_begin;
00328
00329 if (x_ptr > y_ptr)
00330 return 1;
00331 if (x_ptr < y_ptr)
00332 return -1;
00333 return 0;
00334 }
00335
00336 static int
00337 fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
00338 {
00339 _Unwind_Ptr base, x_ptr, y_ptr;
00340
00341 base = base_from_object (ob->s.b.encoding, ob);
00342 read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
00343 read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
00344
00345 if (x_ptr > y_ptr)
00346 return 1;
00347 if (x_ptr < y_ptr)
00348 return -1;
00349 return 0;
00350 }
00351
00352 static int
00353 fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
00354 {
00355 int x_encoding, y_encoding;
00356 _Unwind_Ptr x_ptr, y_ptr;
00357
00358 x_encoding = get_fde_encoding (x);
00359 read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
00360 x->pc_begin, &x_ptr);
00361
00362 y_encoding = get_fde_encoding (y);
00363 read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
00364 y->pc_begin, &y_ptr);
00365
00366 if (x_ptr > y_ptr)
00367 return 1;
00368 if (x_ptr < y_ptr)
00369 return -1;
00370 return 0;
00371 }
00372
00373 typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 struct fde_accumulator
00388 {
00389 struct fde_vector *linear;
00390 struct fde_vector *erratic;
00391 };
00392
00393 static inline int
00394 start_fde_sort (struct fde_accumulator *accu, size_t count)
00395 {
00396 size_t size;
00397 if (! count)
00398 return 0;
00399
00400 size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
00401 if ((accu->linear = malloc (size)))
00402 {
00403 accu->linear->count = 0;
00404 if ((accu->erratic = malloc (size)))
00405 accu->erratic->count = 0;
00406 return 1;
00407 }
00408 else
00409 return 0;
00410 }
00411
00412 static inline void
00413 fde_insert (struct fde_accumulator *accu, const fde *this_fde)
00414 {
00415 if (accu->linear)
00416 accu->linear->array[accu->linear->count++] = this_fde;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 static inline void
00432 fde_split (struct object *ob, fde_compare_t fde_compare,
00433 struct fde_vector *linear, struct fde_vector *erratic)
00434 {
00435 static const fde *marker;
00436 size_t count = linear->count;
00437 const fde **chain_end = ▮
00438 size_t i, j, k;
00439
00440
00441
00442
00443 gcc_assert (sizeof (const fde *) == sizeof (const fde **));
00444
00445 for (i = 0; i < count; i++)
00446 {
00447 const fde **probe;
00448
00449 for (probe = chain_end;
00450 probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
00451 probe = chain_end)
00452 {
00453 chain_end = (const fde **) erratic->array[probe - linear->array];
00454 erratic->array[probe - linear->array] = NULL;
00455 }
00456 erratic->array[i] = (const fde *) chain_end;
00457 chain_end = &linear->array[i];
00458 }
00459
00460
00461
00462
00463 for (i = j = k = 0; i < count; i++)
00464 if (erratic->array[i])
00465 linear->array[j++] = linear->array[i];
00466 else
00467 erratic->array[k++] = linear->array[i];
00468 linear->count = j;
00469 erratic->count = k;
00470 }
00471
00472 #define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
00473
00474
00475
00476
00477 static void
00478 frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
00479 int lo, int hi)
00480 {
00481 int i, j;
00482
00483 for (i = lo, j = 2*i+1;
00484 j < hi;
00485 j = 2*i+1)
00486 {
00487 if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
00488 ++j;
00489
00490 if (fde_compare (ob, a[i], a[j]) < 0)
00491 {
00492 SWAP (a[i], a[j]);
00493 i = j;
00494 }
00495 else
00496 break;
00497 }
00498 }
00499
00500
00501
00502
00503 static void
00504 frame_heapsort (struct object *ob, fde_compare_t fde_compare,
00505 struct fde_vector *erratic)
00506 {
00507
00508
00509
00510 const fde ** a = erratic->array;
00511
00512
00513
00514 size_t n = erratic->count;
00515 int m;
00516
00517
00518
00519
00520 for (m = n/2-1; m >= 0; --m)
00521 frame_downheap (ob, fde_compare, a, m, n);
00522
00523
00524
00525
00526 for (m = n-1; m >= 1; --m)
00527 {
00528 SWAP (a[0], a[m]);
00529 frame_downheap (ob, fde_compare, a, 0, m);
00530 }
00531 #undef SWAP
00532 }
00533
00534
00535 static inline void
00536 fde_merge (struct object *ob, fde_compare_t fde_compare,
00537 struct fde_vector *v1, struct fde_vector *v2)
00538 {
00539 size_t i1, i2;
00540 const fde * fde2;
00541
00542 i2 = v2->count;
00543 if (i2 > 0)
00544 {
00545 i1 = v1->count;
00546 do
00547 {
00548 i2--;
00549 fde2 = v2->array[i2];
00550 while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
00551 {
00552 v1->array[i1+i2] = v1->array[i1-1];
00553 i1--;
00554 }
00555 v1->array[i1+i2] = fde2;
00556 }
00557 while (i2 > 0);
00558 v1->count += v2->count;
00559 }
00560 }
00561
00562 static inline void
00563 end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
00564 {
00565 fde_compare_t fde_compare;
00566
00567 gcc_assert (!accu->linear || accu->linear->count == count);
00568
00569 if (ob->s.b.mixed_encoding)
00570 fde_compare = fde_mixed_encoding_compare;
00571 else if (ob->s.b.encoding == DW_EH_PE_absptr)
00572 fde_compare = fde_unencoded_compare;
00573 else
00574 fde_compare = fde_single_encoding_compare;
00575
00576 if (accu->erratic)
00577 {
00578 fde_split (ob, fde_compare, accu->linear, accu->erratic);
00579 gcc_assert (accu->linear->count + accu->erratic->count == count);
00580 frame_heapsort (ob, fde_compare, accu->erratic);
00581 fde_merge (ob, fde_compare, accu->linear, accu->erratic);
00582 free (accu->erratic);
00583 }
00584 else
00585 {
00586
00587
00588 frame_heapsort (ob, fde_compare, accu->linear);
00589 }
00590 }
00591
00592
00593
00594
00595
00596
00597 static size_t
00598 classify_object_over_fdes (struct object *ob, const fde *this_fde)
00599 {
00600 const struct dwarf_cie *last_cie = 0;
00601 size_t count = 0;
00602 int encoding = DW_EH_PE_absptr;
00603 _Unwind_Ptr base = 0;
00604
00605 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
00606 {
00607 const struct dwarf_cie *this_cie;
00608 _Unwind_Ptr mask, pc_begin;
00609
00610
00611 if (this_fde->CIE_delta == 0)
00612 continue;
00613
00614
00615
00616 this_cie = get_cie (this_fde);
00617 if (this_cie != last_cie)
00618 {
00619 last_cie = this_cie;
00620 encoding = get_cie_encoding (this_cie);
00621 base = base_from_object (encoding, ob);
00622 if (ob->s.b.encoding == DW_EH_PE_omit)
00623 ob->s.b.encoding = encoding;
00624 else if (ob->s.b.encoding != encoding)
00625 ob->s.b.mixed_encoding = 1;
00626 }
00627
00628 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
00629 &pc_begin);
00630
00631
00632
00633
00634
00635 mask = size_of_encoded_value (encoding);
00636 if (mask < sizeof (void *))
00637 mask = (1L << (mask << 3)) - 1;
00638 else
00639 mask = -1;
00640
00641 if ((pc_begin & mask) == 0)
00642 continue;
00643
00644 count += 1;
00645 if ((void *) pc_begin < ob->pc_begin)
00646 ob->pc_begin = (void *) pc_begin;
00647 }
00648
00649 return count;
00650 }
00651
00652 static void
00653 add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
00654 {
00655 const struct dwarf_cie *last_cie = 0;
00656 int encoding = ob->s.b.encoding;
00657 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
00658
00659 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
00660 {
00661 const struct dwarf_cie *this_cie;
00662
00663
00664 if (this_fde->CIE_delta == 0)
00665 continue;
00666
00667 if (ob->s.b.mixed_encoding)
00668 {
00669
00670
00671 this_cie = get_cie (this_fde);
00672 if (this_cie != last_cie)
00673 {
00674 last_cie = this_cie;
00675 encoding = get_cie_encoding (this_cie);
00676 base = base_from_object (encoding, ob);
00677 }
00678 }
00679
00680 if (encoding == DW_EH_PE_absptr)
00681 {
00682 if (*(_Unwind_Ptr *) this_fde->pc_begin == 0)
00683 continue;
00684 }
00685 else
00686 {
00687 _Unwind_Ptr pc_begin, mask;
00688
00689 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
00690 &pc_begin);
00691
00692
00693
00694
00695
00696 mask = size_of_encoded_value (encoding);
00697 if (mask < sizeof (void *))
00698 mask = (1L << (mask << 3)) - 1;
00699 else
00700 mask = -1;
00701
00702 if ((pc_begin & mask) == 0)
00703 continue;
00704 }
00705
00706 fde_insert (accu, this_fde);
00707 }
00708 }
00709
00710
00711
00712
00713
00714
00715 static inline void
00716 init_object (struct object* ob)
00717 {
00718 struct fde_accumulator accu;
00719 size_t count;
00720
00721 count = ob->s.b.count;
00722 if (count == 0)
00723 {
00724 if (ob->s.b.from_array)
00725 {
00726 fde **p = ob->u.array;
00727 for (count = 0; *p; ++p)
00728 count += classify_object_over_fdes (ob, *p);
00729 }
00730 else
00731 count = classify_object_over_fdes (ob, ob->u.single);
00732
00733
00734
00735
00736
00737
00738 ob->s.b.count = count;
00739 if (ob->s.b.count != count)
00740 ob->s.b.count = 0;
00741 }
00742
00743 if (!start_fde_sort (&accu, count))
00744 return;
00745
00746 if (ob->s.b.from_array)
00747 {
00748 fde **p;
00749 for (p = ob->u.array; *p; ++p)
00750 add_fdes (ob, &accu, *p);
00751 }
00752 else
00753 add_fdes (ob, &accu, ob->u.single);
00754
00755 end_fde_sort (ob, &accu, count);
00756
00757
00758
00759 accu.linear->orig_data = ob->u.single;
00760 ob->u.sort = accu.linear;
00761
00762 ob->s.b.sorted = 1;
00763 }
00764
00765
00766
00767
00768
00769 static const fde *
00770 linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
00771 {
00772 const struct dwarf_cie *last_cie = 0;
00773 int encoding = ob->s.b.encoding;
00774 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
00775
00776 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
00777 {
00778 const struct dwarf_cie *this_cie;
00779 _Unwind_Ptr pc_begin, pc_range;
00780
00781
00782 if (this_fde->CIE_delta == 0)
00783 continue;
00784
00785 if (ob->s.b.mixed_encoding)
00786 {
00787
00788
00789 this_cie = get_cie (this_fde);
00790 if (this_cie != last_cie)
00791 {
00792 last_cie = this_cie;
00793 encoding = get_cie_encoding (this_cie);
00794 base = base_from_object (encoding, ob);
00795 }
00796 }
00797
00798 if (encoding == DW_EH_PE_absptr)
00799 {
00800 pc_begin = ((_Unwind_Ptr *) this_fde->pc_begin)[0];
00801 pc_range = ((_Unwind_Ptr *) this_fde->pc_begin)[1];
00802 if (pc_begin == 0)
00803 continue;
00804 }
00805 else
00806 {
00807 _Unwind_Ptr mask;
00808 const unsigned char *p;
00809
00810 p = read_encoded_value_with_base (encoding, base,
00811 this_fde->pc_begin, &pc_begin);
00812 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
00813
00814
00815
00816
00817
00818 mask = size_of_encoded_value (encoding);
00819 if (mask < sizeof (void *))
00820 mask = (1L << (mask << 3)) - 1;
00821 else
00822 mask = -1;
00823
00824 if ((pc_begin & mask) == 0)
00825 continue;
00826 }
00827
00828 if ((_Unwind_Ptr) pc - pc_begin < pc_range)
00829 return this_fde;
00830 }
00831
00832 return NULL;
00833 }
00834
00835
00836
00837
00838 static inline const fde *
00839 binary_search_unencoded_fdes (struct object *ob, void *pc)
00840 {
00841 struct fde_vector *vec = ob->u.sort;
00842 size_t lo, hi;
00843
00844 for (lo = 0, hi = vec->count; lo < hi; )
00845 {
00846 size_t i = (lo + hi) / 2;
00847 const fde *f = vec->array[i];
00848 void *pc_begin;
00849 uaddr pc_range;
00850
00851 pc_begin = ((void **) f->pc_begin)[0];
00852 pc_range = ((uaddr *) f->pc_begin)[1];
00853
00854 if (pc < pc_begin)
00855 hi = i;
00856 else if (pc >= pc_begin + pc_range)
00857 lo = i + 1;
00858 else
00859 return f;
00860 }
00861
00862 return NULL;
00863 }
00864
00865 static inline const fde *
00866 binary_search_single_encoding_fdes (struct object *ob, void *pc)
00867 {
00868 struct fde_vector *vec = ob->u.sort;
00869 int encoding = ob->s.b.encoding;
00870 _Unwind_Ptr base = base_from_object (encoding, ob);
00871 size_t lo, hi;
00872
00873 for (lo = 0, hi = vec->count; lo < hi; )
00874 {
00875 size_t i = (lo + hi) / 2;
00876 const fde *f = vec->array[i];
00877 _Unwind_Ptr pc_begin, pc_range;
00878 const unsigned char *p;
00879
00880 p = read_encoded_value_with_base (encoding, base, f->pc_begin,
00881 &pc_begin);
00882 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
00883
00884 if ((_Unwind_Ptr) pc < pc_begin)
00885 hi = i;
00886 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
00887 lo = i + 1;
00888 else
00889 return f;
00890 }
00891
00892 return NULL;
00893 }
00894
00895 static inline const fde *
00896 binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
00897 {
00898 struct fde_vector *vec = ob->u.sort;
00899 size_t lo, hi;
00900
00901 for (lo = 0, hi = vec->count; lo < hi; )
00902 {
00903 size_t i = (lo + hi) / 2;
00904 const fde *f = vec->array[i];
00905 _Unwind_Ptr pc_begin, pc_range;
00906 const unsigned char *p;
00907 int encoding;
00908
00909 encoding = get_fde_encoding (f);
00910 p = read_encoded_value_with_base (encoding,
00911 base_from_object (encoding, ob),
00912 f->pc_begin, &pc_begin);
00913 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
00914
00915 if ((_Unwind_Ptr) pc < pc_begin)
00916 hi = i;
00917 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
00918 lo = i + 1;
00919 else
00920 return f;
00921 }
00922
00923 return NULL;
00924 }
00925
00926 static const fde *
00927 search_object (struct object* ob, void *pc)
00928 {
00929
00930
00931 if (! ob->s.b.sorted)
00932 {
00933 init_object (ob);
00934
00935
00936
00937
00938 if (pc < ob->pc_begin)
00939 return NULL;
00940 }
00941
00942 if (ob->s.b.sorted)
00943 {
00944 if (ob->s.b.mixed_encoding)
00945 return binary_search_mixed_encoding_fdes (ob, pc);
00946 else if (ob->s.b.encoding == DW_EH_PE_absptr)
00947 return binary_search_unencoded_fdes (ob, pc);
00948 else
00949 return binary_search_single_encoding_fdes (ob, pc);
00950 }
00951 else
00952 {
00953
00954 if (ob->s.b.from_array)
00955 {
00956 fde **p;
00957 for (p = ob->u.array; *p ; p++)
00958 {
00959 const fde *f = linear_search_fdes (ob, *p, pc);
00960 if (f)
00961 return f;
00962 }
00963 return NULL;
00964 }
00965 else
00966 return linear_search_fdes (ob, ob->u.single, pc);
00967 }
00968 }
00969
00970 const fde *
00971 _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
00972 {
00973 struct object *ob;
00974 const fde *f = NULL;
00975
00976 init_object_mutex_once ();
00977 __gthread_mutex_lock (&object_mutex);
00978
00979
00980
00981
00982 for (ob = seen_objects; ob; ob = ob->next)
00983 if (pc >= ob->pc_begin)
00984 {
00985 f = search_object (ob, pc);
00986 if (f)
00987 goto fini;
00988 break;
00989 }
00990
00991
00992 while ((ob = unseen_objects))
00993 {
00994 struct object **p;
00995
00996 unseen_objects = ob->next;
00997 f = search_object (ob, pc);
00998
00999
01000 for (p = &seen_objects; *p ; p = &(*p)->next)
01001 if ((*p)->pc_begin < ob->pc_begin)
01002 break;
01003 ob->next = *p;
01004 *p = ob;
01005
01006 if (f)
01007 goto fini;
01008 }
01009
01010 fini:
01011 __gthread_mutex_unlock (&object_mutex);
01012
01013 if (f)
01014 {
01015 int encoding;
01016 _Unwind_Ptr func;
01017
01018 bases->tbase = ob->tbase;
01019 bases->dbase = ob->dbase;
01020
01021 encoding = ob->s.b.encoding;
01022 if (ob->s.b.mixed_encoding)
01023 encoding = get_fde_encoding (f);
01024 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
01025 f->pc_begin, &func);
01026 bases->func = (void *) func;
01027 }
01028
01029 return f;
01030 }