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