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 __gthread_mutex_unlock (&object_mutex);
00216 abort ();
00217
00218 out:
00219 __gthread_mutex_unlock (&object_mutex);
00220 return (void *) ob;
00221 }
00222
00223 void *
00224 __deregister_frame_info (const void *begin)
00225 {
00226 return __deregister_frame_info_bases (begin);
00227 }
00228
00229 void
00230 __deregister_frame (void *begin)
00231 {
00232
00233 if (*(uword *) begin != 0)
00234 free (__deregister_frame_info (begin));
00235 }
00236
00237
00238
00239
00240
00241 static _Unwind_Ptr
00242 base_from_object (unsigned char encoding, struct object *ob)
00243 {
00244 if (encoding == DW_EH_PE_omit)
00245 return 0;
00246
00247 switch (encoding & 0x70)
00248 {
00249 case DW_EH_PE_absptr:
00250 case DW_EH_PE_pcrel:
00251 case DW_EH_PE_aligned:
00252 return 0;
00253
00254 case DW_EH_PE_textrel:
00255 return (_Unwind_Ptr) ob->tbase;
00256 case DW_EH_PE_datarel:
00257 return (_Unwind_Ptr) ob->dbase;
00258 }
00259 abort ();
00260 }
00261
00262
00263
00264
00265 static int
00266 get_cie_encoding (const struct dwarf_cie *cie)
00267 {
00268 const unsigned char *aug, *p;
00269 _Unwind_Ptr dummy;
00270 _Unwind_Word utmp;
00271 _Unwind_Sword stmp;
00272
00273 aug = cie->augmentation;
00274 if (aug[0] != 'z')
00275 return DW_EH_PE_absptr;
00276
00277 p = aug + strlen ((const char *)aug) + 1;
00278 p = read_uleb128 (p, &utmp);
00279 p = read_sleb128 (p, &stmp);
00280 if (cie->version == 1)
00281 p++;
00282 else
00283 p = read_uleb128 (p, &utmp);
00284
00285 aug++;
00286 p = read_uleb128 (p, &utmp);
00287 while (1)
00288 {
00289
00290 if (*aug == 'R')
00291 return *p;
00292
00293 else if (*aug == 'P')
00294 {
00295
00296
00297
00298 p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
00299 }
00300
00301 else if (*aug == 'L')
00302 p++;
00303
00304 else
00305 return DW_EH_PE_absptr;
00306 aug++;
00307 }
00308 }
00309
00310 static inline int
00311 get_fde_encoding (const struct dwarf_fde *f)
00312 {
00313 return get_cie_encoding (get_cie (f));
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 static int
00324 fde_unencoded_compare (struct object *ob __attribute__((unused)),
00325 const fde *x, const fde *y)
00326 {
00327 _Unwind_Ptr x_ptr = *(_Unwind_Ptr *) x->pc_begin;
00328 _Unwind_Ptr y_ptr = *(_Unwind_Ptr *) y->pc_begin;
00329
00330 if (x_ptr > y_ptr)
00331 return 1;
00332 if (x_ptr < y_ptr)
00333 return -1;
00334 return 0;
00335 }
00336
00337 static int
00338 fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
00339 {
00340 _Unwind_Ptr base, x_ptr, y_ptr;
00341
00342 base = base_from_object (ob->s.b.encoding, ob);
00343 read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
00344 read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
00345
00346 if (x_ptr > y_ptr)
00347 return 1;
00348 if (x_ptr < y_ptr)
00349 return -1;
00350 return 0;
00351 }
00352
00353 static int
00354 fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
00355 {
00356 int x_encoding, y_encoding;
00357 _Unwind_Ptr x_ptr, y_ptr;
00358
00359 x_encoding = get_fde_encoding (x);
00360 read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
00361 x->pc_begin, &x_ptr);
00362
00363 y_encoding = get_fde_encoding (y);
00364 read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
00365 y->pc_begin, &y_ptr);
00366
00367 if (x_ptr > y_ptr)
00368 return 1;
00369 if (x_ptr < y_ptr)
00370 return -1;
00371 return 0;
00372 }
00373
00374 typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 struct fde_accumulator
00389 {
00390 struct fde_vector *linear;
00391 struct fde_vector *erratic;
00392 };
00393
00394 static inline int
00395 start_fde_sort (struct fde_accumulator *accu, size_t count)
00396 {
00397 size_t size;
00398 if (! count)
00399 return 0;
00400
00401 size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
00402 if ((accu->linear = malloc (size)))
00403 {
00404 accu->linear->count = 0;
00405 if ((accu->erratic = malloc (size)))
00406 accu->erratic->count = 0;
00407 return 1;
00408 }
00409 else
00410 return 0;
00411 }
00412
00413 static inline void
00414 fde_insert (struct fde_accumulator *accu, const fde *this_fde)
00415 {
00416 if (accu->linear)
00417 accu->linear->array[accu->linear->count++] = this_fde;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static inline void
00433 fde_split (struct object *ob, fde_compare_t fde_compare,
00434 struct fde_vector *linear, struct fde_vector *erratic)
00435 {
00436 static const fde *marker;
00437 size_t count = linear->count;
00438 const fde **chain_end = ▮
00439 size_t i, j, k;
00440
00441
00442
00443
00444 if (sizeof (const fde *) != sizeof (const fde **))
00445 abort ();
00446
00447 for (i = 0; i < count; i++)
00448 {
00449 const fde **probe;
00450
00451 for (probe = chain_end;
00452 probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
00453 probe = chain_end)
00454 {
00455 chain_end = (const fde **) erratic->array[probe - linear->array];
00456 erratic->array[probe - linear->array] = NULL;
00457 }
00458 erratic->array[i] = (const fde *) chain_end;
00459 chain_end = &linear->array[i];
00460 }
00461
00462
00463
00464
00465 for (i = j = k = 0; i < count; i++)
00466 if (erratic->array[i])
00467 linear->array[j++] = linear->array[i];
00468 else
00469 erratic->array[k++] = linear->array[i];
00470 linear->count = j;
00471 erratic->count = k;
00472 }
00473
00474 #define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
00475
00476
00477
00478
00479 static void
00480 frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
00481 int lo, int hi)
00482 {
00483 int i, j;
00484
00485 for (i = lo, j = 2*i+1;
00486 j < hi;
00487 j = 2*i+1)
00488 {
00489 if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
00490 ++j;
00491
00492 if (fde_compare (ob, a[i], a[j]) < 0)
00493 {
00494 SWAP (a[i], a[j]);
00495 i = j;
00496 }
00497 else
00498 break;
00499 }
00500 }
00501
00502
00503
00504
00505 static void
00506 frame_heapsort (struct object *ob, fde_compare_t fde_compare,
00507 struct fde_vector *erratic)
00508 {
00509
00510
00511
00512 const fde ** a = erratic->array;
00513
00514
00515
00516 size_t n = erratic->count;
00517 int m;
00518
00519
00520
00521
00522 for (m = n/2-1; m >= 0; --m)
00523 frame_downheap (ob, fde_compare, a, m, n);
00524
00525
00526
00527
00528 for (m = n-1; m >= 1; --m)
00529 {
00530 SWAP (a[0], a[m]);
00531 frame_downheap (ob, fde_compare, a, 0, m);
00532 }
00533 #undef SWAP
00534 }
00535
00536
00537 static inline void
00538 fde_merge (struct object *ob, fde_compare_t fde_compare,
00539 struct fde_vector *v1, struct fde_vector *v2)
00540 {
00541 size_t i1, i2;
00542 const fde * fde2;
00543
00544 i2 = v2->count;
00545 if (i2 > 0)
00546 {
00547 i1 = v1->count;
00548 do
00549 {
00550 i2--;
00551 fde2 = v2->array[i2];
00552 while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
00553 {
00554 v1->array[i1+i2] = v1->array[i1-1];
00555 i1--;
00556 }
00557 v1->array[i1+i2] = fde2;
00558 }
00559 while (i2 > 0);
00560 v1->count += v2->count;
00561 }
00562 }
00563
00564 static inline void
00565 end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
00566 {
00567 fde_compare_t fde_compare;
00568
00569 if (accu->linear && accu->linear->count != count)
00570 abort ();
00571
00572 if (ob->s.b.mixed_encoding)
00573 fde_compare = fde_mixed_encoding_compare;
00574 else if (ob->s.b.encoding == DW_EH_PE_absptr)
00575 fde_compare = fde_unencoded_compare;
00576 else
00577 fde_compare = fde_single_encoding_compare;
00578
00579 if (accu->erratic)
00580 {
00581 fde_split (ob, fde_compare, accu->linear, accu->erratic);
00582 if (accu->linear->count + accu->erratic->count != count)
00583 abort ();
00584 frame_heapsort (ob, fde_compare, accu->erratic);
00585 fde_merge (ob, fde_compare, accu->linear, accu->erratic);
00586 free (accu->erratic);
00587 }
00588 else
00589 {
00590
00591
00592 frame_heapsort (ob, fde_compare, accu->linear);
00593 }
00594 }
00595
00596
00597
00598
00599
00600
00601 static size_t
00602 classify_object_over_fdes (struct object *ob, const fde *this_fde)
00603 {
00604 const struct dwarf_cie *last_cie = 0;
00605 size_t count = 0;
00606 int encoding = DW_EH_PE_absptr;
00607 _Unwind_Ptr base = 0;
00608
00609 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
00610 {
00611 const struct dwarf_cie *this_cie;
00612 _Unwind_Ptr mask, pc_begin;
00613
00614
00615 if (this_fde->CIE_delta == 0)
00616 continue;
00617
00618
00619
00620 this_cie = get_cie (this_fde);
00621 if (this_cie != last_cie)
00622 {
00623 last_cie = this_cie;
00624 encoding = get_cie_encoding (this_cie);
00625 base = base_from_object (encoding, ob);
00626 if (ob->s.b.encoding == DW_EH_PE_omit)
00627 ob->s.b.encoding = encoding;
00628 else if (ob->s.b.encoding != encoding)
00629 ob->s.b.mixed_encoding = 1;
00630 }
00631
00632 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
00633 &pc_begin);
00634
00635
00636
00637
00638
00639 mask = size_of_encoded_value (encoding);
00640 if (mask < sizeof (void *))
00641 mask = (1L << (mask << 3)) - 1;
00642 else
00643 mask = -1;
00644
00645 if ((pc_begin & mask) == 0)
00646 continue;
00647
00648 count += 1;
00649 if ((void *) pc_begin < ob->pc_begin)
00650 ob->pc_begin = (void *) pc_begin;
00651 }
00652
00653 return count;
00654 }
00655
00656 static void
00657 add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
00658 {
00659 const struct dwarf_cie *last_cie = 0;
00660 int encoding = ob->s.b.encoding;
00661 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
00662
00663 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
00664 {
00665 const struct dwarf_cie *this_cie;
00666
00667
00668 if (this_fde->CIE_delta == 0)
00669 continue;
00670
00671 if (ob->s.b.mixed_encoding)
00672 {
00673
00674
00675 this_cie = get_cie (this_fde);
00676 if (this_cie != last_cie)
00677 {
00678 last_cie = this_cie;
00679 encoding = get_cie_encoding (this_cie);
00680 base = base_from_object (encoding, ob);
00681 }
00682 }
00683
00684 if (encoding == DW_EH_PE_absptr)
00685 {
00686 if (*(_Unwind_Ptr *) this_fde->pc_begin == 0)
00687 continue;
00688 }
00689 else
00690 {
00691 _Unwind_Ptr pc_begin, mask;
00692
00693 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
00694 &pc_begin);
00695
00696
00697
00698
00699
00700 mask = size_of_encoded_value (encoding);
00701 if (mask < sizeof (void *))
00702 mask = (1L << (mask << 3)) - 1;
00703 else
00704 mask = -1;
00705
00706 if ((pc_begin & mask) == 0)
00707 continue;
00708 }
00709
00710 fde_insert (accu, this_fde);
00711 }
00712 }
00713
00714
00715
00716
00717
00718
00719 static inline void
00720 init_object (struct object* ob)
00721 {
00722 struct fde_accumulator accu;
00723 size_t count;
00724
00725 count = ob->s.b.count;
00726 if (count == 0)
00727 {
00728 if (ob->s.b.from_array)
00729 {
00730 fde **p = ob->u.array;
00731 for (count = 0; *p; ++p)
00732 count += classify_object_over_fdes (ob, *p);
00733 }
00734 else
00735 count = classify_object_over_fdes (ob, ob->u.single);
00736
00737
00738
00739
00740
00741
00742 ob->s.b.count = count;
00743 if (ob->s.b.count != count)
00744 ob->s.b.count = 0;
00745 }
00746
00747 if (!start_fde_sort (&accu, count))
00748 return;
00749
00750 if (ob->s.b.from_array)
00751 {
00752 fde **p;
00753 for (p = ob->u.array; *p; ++p)
00754 add_fdes (ob, &accu, *p);
00755 }
00756 else
00757 add_fdes (ob, &accu, ob->u.single);
00758
00759 end_fde_sort (ob, &accu, count);
00760
00761
00762
00763 accu.linear->orig_data = ob->u.single;
00764 ob->u.sort = accu.linear;
00765
00766 ob->s.b.sorted = 1;
00767 }
00768
00769
00770
00771
00772
00773 static const fde *
00774 linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
00775 {
00776 const struct dwarf_cie *last_cie = 0;
00777 int encoding = ob->s.b.encoding;
00778 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
00779
00780 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
00781 {
00782 const struct dwarf_cie *this_cie;
00783 _Unwind_Ptr pc_begin, pc_range;
00784
00785
00786 if (this_fde->CIE_delta == 0)
00787 continue;
00788
00789 if (ob->s.b.mixed_encoding)
00790 {
00791
00792
00793 this_cie = get_cie (this_fde);
00794 if (this_cie != last_cie)
00795 {
00796 last_cie = this_cie;
00797 encoding = get_cie_encoding (this_cie);
00798 base = base_from_object (encoding, ob);
00799 }
00800 }
00801
00802 if (encoding == DW_EH_PE_absptr)
00803 {
00804 pc_begin = ((_Unwind_Ptr *) this_fde->pc_begin)[0];
00805 pc_range = ((_Unwind_Ptr *) this_fde->pc_begin)[1];
00806 if (pc_begin == 0)
00807 continue;
00808 }
00809 else
00810 {
00811 _Unwind_Ptr mask;
00812 const unsigned char *p;
00813
00814 p = read_encoded_value_with_base (encoding, base,
00815 this_fde->pc_begin, &pc_begin);
00816 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
00817
00818
00819
00820
00821
00822 mask = size_of_encoded_value (encoding);
00823 if (mask < sizeof (void *))
00824 mask = (1L << (mask << 3)) - 1;
00825 else
00826 mask = -1;
00827
00828 if ((pc_begin & mask) == 0)
00829 continue;
00830 }
00831
00832 if ((_Unwind_Ptr) pc - pc_begin < pc_range)
00833 return this_fde;
00834 }
00835
00836 return NULL;
00837 }
00838
00839
00840
00841
00842 static inline const fde *
00843 binary_search_unencoded_fdes (struct object *ob, void *pc)
00844 {
00845 struct fde_vector *vec = ob->u.sort;
00846 size_t lo, hi;
00847
00848 for (lo = 0, hi = vec->count; lo < hi; )
00849 {
00850 size_t i = (lo + hi) / 2;
00851 const fde *f = vec->array[i];
00852 void *pc_begin;
00853 uaddr pc_range;
00854
00855 pc_begin = ((void **) f->pc_begin)[0];
00856 pc_range = ((uaddr *) f->pc_begin)[1];
00857
00858 if (pc < pc_begin)
00859 hi = i;
00860 else if (pc >= pc_begin + pc_range)
00861 lo = i + 1;
00862 else
00863 return f;
00864 }
00865
00866 return NULL;
00867 }
00868
00869 static inline const fde *
00870 binary_search_single_encoding_fdes (struct object *ob, void *pc)
00871 {
00872 struct fde_vector *vec = ob->u.sort;
00873 int encoding = ob->s.b.encoding;
00874 _Unwind_Ptr base = base_from_object (encoding, ob);
00875 size_t lo, hi;
00876
00877 for (lo = 0, hi = vec->count; lo < hi; )
00878 {
00879 size_t i = (lo + hi) / 2;
00880 const fde *f = vec->array[i];
00881 _Unwind_Ptr pc_begin, pc_range;
00882 const unsigned char *p;
00883
00884 p = read_encoded_value_with_base (encoding, base, f->pc_begin,
00885 &pc_begin);
00886 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
00887
00888 if ((_Unwind_Ptr) pc < pc_begin)
00889 hi = i;
00890 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
00891 lo = i + 1;
00892 else
00893 return f;
00894 }
00895
00896 return NULL;
00897 }
00898
00899 static inline const fde *
00900 binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
00901 {
00902 struct fde_vector *vec = ob->u.sort;
00903 size_t lo, hi;
00904
00905 for (lo = 0, hi = vec->count; lo < hi; )
00906 {
00907 size_t i = (lo + hi) / 2;
00908 const fde *f = vec->array[i];
00909 _Unwind_Ptr pc_begin, pc_range;
00910 const unsigned char *p;
00911 int encoding;
00912
00913 encoding = get_fde_encoding (f);
00914 p = read_encoded_value_with_base (encoding,
00915 base_from_object (encoding, ob),
00916 f->pc_begin, &pc_begin);
00917 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
00918
00919 if ((_Unwind_Ptr) pc < pc_begin)
00920 hi = i;
00921 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
00922 lo = i + 1;
00923 else
00924 return f;
00925 }
00926
00927 return NULL;
00928 }
00929
00930 static const fde *
00931 search_object (struct object* ob, void *pc)
00932 {
00933
00934
00935 if (! ob->s.b.sorted)
00936 {
00937 init_object (ob);
00938
00939
00940
00941
00942 if (pc < ob->pc_begin)
00943 return NULL;
00944 }
00945
00946 if (ob->s.b.sorted)
00947 {
00948 if (ob->s.b.mixed_encoding)
00949 return binary_search_mixed_encoding_fdes (ob, pc);
00950 else if (ob->s.b.encoding == DW_EH_PE_absptr)
00951 return binary_search_unencoded_fdes (ob, pc);
00952 else
00953 return binary_search_single_encoding_fdes (ob, pc);
00954 }
00955 else
00956 {
00957
00958 if (ob->s.b.from_array)
00959 {
00960 fde **p;
00961 for (p = ob->u.array; *p ; p++)
00962 {
00963 const fde *f = linear_search_fdes (ob, *p, pc);
00964 if (f)
00965 return f;
00966 }
00967 return NULL;
00968 }
00969 else
00970 return linear_search_fdes (ob, ob->u.single, pc);
00971 }
00972 }
00973
00974 const fde *
00975 _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
00976 {
00977 struct object *ob;
00978 const fde *f = NULL;
00979
00980 init_object_mutex_once ();
00981 __gthread_mutex_lock (&object_mutex);
00982
00983
00984
00985
00986 for (ob = seen_objects; ob; ob = ob->next)
00987 if (pc >= ob->pc_begin)
00988 {
00989 f = search_object (ob, pc);
00990 if (f)
00991 goto fini;
00992 break;
00993 }
00994
00995
00996 while ((ob = unseen_objects))
00997 {
00998 struct object **p;
00999
01000 unseen_objects = ob->next;
01001 f = search_object (ob, pc);
01002
01003
01004 for (p = &seen_objects; *p ; p = &(*p)->next)
01005 if ((*p)->pc_begin < ob->pc_begin)
01006 break;
01007 ob->next = *p;
01008 *p = ob;
01009
01010 if (f)
01011 goto fini;
01012 }
01013
01014 fini:
01015 __gthread_mutex_unlock (&object_mutex);
01016
01017 if (f)
01018 {
01019 int encoding;
01020
01021 bases->tbase = ob->tbase;
01022 bases->dbase = ob->dbase;
01023
01024 encoding = ob->s.b.encoding;
01025 if (ob->s.b.mixed_encoding)
01026 encoding = get_fde_encoding (f);
01027 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
01028 f->pc_begin, (_Unwind_Ptr *)&bases->func);
01029 }
01030
01031 return f;
01032 }