ada: Reorder components in Ada.Containers.Bounded_Doubly_Linked_Lists
[official-gcc.git] / libgcc / unwind-dw2-fde.c
bloba5786bf729ce3a940be745488ca58cadc6ab4a86
1 /* Subroutines needed for unwinding stack frames for exception handling. */
2 /* Copyright (C) 1997-2023 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 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 #ifndef _Unwind_Find_FDE
27 #include "tconfig.h"
28 #include "tsystem.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "libgcc_tm.h"
32 #include "dwarf2.h"
33 #include "unwind.h"
34 #define NO_BASE_OF_ENCODED_VALUE
35 #include "unwind-pe.h"
36 #include "unwind-dw2-fde.h"
37 #include "gthr.h"
38 #else
39 #if (defined(__GTHREAD_MUTEX_INIT) || defined(__GTHREAD_MUTEX_INIT_FUNCTION)) \
40 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
41 #define ATOMIC_FDE_FAST_PATH 1
42 #endif
43 #endif
45 typedef __UINTPTR_TYPE__ uintptr_type;
47 #ifdef ATOMIC_FDE_FAST_PATH
48 #include "unwind-dw2-btree.h"
50 static struct btree registered_frames;
51 static bool in_shutdown;
53 static void
54 release_registered_frames (void) __attribute__ ((destructor));
55 static void
56 release_registered_frames (void)
58 /* Release the b-tree and all frames. Frame releases that happen later are
59 * silently ignored */
60 btree_destroy (&registered_frames);
61 in_shutdown = true;
64 static void
65 get_pc_range (const struct object *ob, uintptr_type *range);
67 #else
68 /* Without fast path frame deregistration must always succeed. */
69 static const int in_shutdown = 0;
71 /* The unseen_objects list contains objects that have been registered
72 but not yet categorized in any way. The seen_objects list has had
73 its pc_begin and count fields initialized at minimum, and is sorted
74 by decreasing value of pc_begin. */
75 static struct object *unseen_objects;
76 static struct object *seen_objects;
77 #endif
79 #ifdef __GTHREAD_MUTEX_INIT
80 static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
81 #define init_object_mutex_once()
82 #else
83 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
84 static __gthread_mutex_t object_mutex;
86 static void
87 init_object_mutex (void)
89 __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
92 static void
93 init_object_mutex_once (void)
95 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
96 __gthread_once (&once, init_object_mutex);
98 #else
99 /* ??? Several targets include this file with stubbing parts of gthr.h
100 and expect no locking to be done. */
101 #define init_object_mutex_once()
102 static __gthread_mutex_t object_mutex;
103 #endif
104 #endif
106 /* Called from crtbegin.o to register the unwind info for an object. */
108 void
109 __register_frame_info_bases (const void *begin, struct object *ob,
110 void *tbase, void *dbase)
112 /* If .eh_frame is empty, don't register at all. */
113 if ((const uword *) begin == 0 || *(const uword *) begin == 0)
114 return;
116 ob->pc_begin = (void *)-1;
117 ob->tbase = tbase;
118 ob->dbase = dbase;
119 ob->u.single = begin;
120 ob->s.i = 0;
121 ob->s.b.encoding = DW_EH_PE_omit;
122 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
123 ob->fde_end = NULL;
124 #endif
126 #ifdef ATOMIC_FDE_FAST_PATH
127 // Register the frame in the b-tree
128 uintptr_type range[2];
129 get_pc_range (ob, range);
130 btree_insert (&registered_frames, range[0], range[1] - range[0], ob);
131 #else
132 init_object_mutex_once ();
133 __gthread_mutex_lock (&object_mutex);
135 ob->next = unseen_objects;
136 unseen_objects = ob;
138 __gthread_mutex_unlock (&object_mutex);
139 #endif
142 void
143 __register_frame_info (const void *begin, struct object *ob)
145 __register_frame_info_bases (begin, ob, 0, 0);
148 void
149 __register_frame (void *begin)
151 struct object *ob;
153 /* If .eh_frame is empty, don't register at all. */
154 if (*(uword *) begin == 0)
155 return;
157 ob = malloc (sizeof (struct object));
158 __register_frame_info (begin, ob);
161 /* Similar, but BEGIN is actually a pointer to a table of unwind entries
162 for different translation units. Called from the file generated by
163 collect2. */
165 void
166 __register_frame_info_table_bases (void *begin, struct object *ob,
167 void *tbase, void *dbase)
169 ob->pc_begin = (void *)-1;
170 ob->tbase = tbase;
171 ob->dbase = dbase;
172 ob->u.array = begin;
173 ob->s.i = 0;
174 ob->s.b.from_array = 1;
175 ob->s.b.encoding = DW_EH_PE_omit;
177 #ifdef ATOMIC_FDE_FAST_PATH
178 // Register the frame in the b-tree
179 uintptr_type range[2];
180 get_pc_range (ob, range);
181 btree_insert (&registered_frames, range[0], range[1] - range[0], ob);
182 #else
183 init_object_mutex_once ();
184 __gthread_mutex_lock (&object_mutex);
186 ob->next = unseen_objects;
187 unseen_objects = ob;
189 __gthread_mutex_unlock (&object_mutex);
190 #endif
193 void
194 __register_frame_info_table (void *begin, struct object *ob)
196 __register_frame_info_table_bases (begin, ob, 0, 0);
199 void
200 __register_frame_table (void *begin)
202 struct object *ob = malloc (sizeof (struct object));
203 __register_frame_info_table (begin, ob);
206 /* Called from crtbegin.o to deregister the unwind info for an object. */
207 /* ??? Glibc has for a while now exported __register_frame_info and
208 __deregister_frame_info. If we call __register_frame_info_bases
209 from crtbegin (wherein it is declared weak), and this object does
210 not get pulled from libgcc.a for other reasons, then the
211 invocation of __deregister_frame_info will be resolved from glibc.
212 Since the registration did not happen there, we'll die.
214 Therefore, declare a new deregistration entry point that does the
215 exact same thing, but will resolve to the same library as
216 implements __register_frame_info_bases. */
218 void *
219 __deregister_frame_info_bases (const void *begin)
221 struct object *ob = 0;
223 /* If .eh_frame is empty, we haven't registered. */
224 if ((const uword *) begin == 0 || *(const uword *) begin == 0)
225 return ob;
227 #ifdef ATOMIC_FDE_FAST_PATH
228 // Find the corresponding PC range
229 struct object lookupob;
230 lookupob.tbase = 0;
231 lookupob.dbase = 0;
232 lookupob.u.single = begin;
233 lookupob.s.i = 0;
234 lookupob.s.b.encoding = DW_EH_PE_omit;
235 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
236 lookupob.fde_end = NULL;
237 #endif
238 uintptr_type range[2];
239 get_pc_range (&lookupob, range);
241 // And remove
242 ob = btree_remove (&registered_frames, range[0]);
243 bool empty_table = (range[1] - range[0]) == 0;
244 #else
245 init_object_mutex_once ();
246 __gthread_mutex_lock (&object_mutex);
248 struct object **p;
249 for (p = &unseen_objects; *p ; p = &(*p)->next)
250 if ((*p)->u.single == begin)
252 ob = *p;
253 *p = ob->next;
254 goto out;
257 for (p = &seen_objects; *p ; p = &(*p)->next)
258 if ((*p)->s.b.sorted)
260 if ((*p)->u.sort->orig_data == begin)
262 ob = *p;
263 *p = ob->next;
264 free (ob->u.sort);
265 goto out;
268 else
270 if ((*p)->u.single == begin)
272 ob = *p;
273 *p = ob->next;
274 goto out;
278 out:
279 __gthread_mutex_unlock (&object_mutex);
280 const int empty_table = 0; // The non-atomic path stores all tables.
281 #endif
283 // If we didn't find anything in the lookup data structures then they
284 // were either already destroyed or we tried to remove an empty range.
285 gcc_assert (in_shutdown || (empty_table || ob));
286 return (void *) ob;
289 void *
290 __deregister_frame_info (const void *begin)
292 return __deregister_frame_info_bases (begin);
295 void
296 __deregister_frame (void *begin)
298 /* If .eh_frame is empty, we haven't registered. */
299 if (*(uword *) begin != 0)
300 free (__deregister_frame_info (begin));
304 /* Like base_of_encoded_value, but take the base from a struct object
305 instead of an _Unwind_Context. */
307 static _Unwind_Ptr
308 base_from_object (unsigned char encoding, const struct object *ob)
310 if (encoding == DW_EH_PE_omit)
311 return 0;
313 switch (encoding & 0x70)
315 case DW_EH_PE_absptr:
316 case DW_EH_PE_pcrel:
317 case DW_EH_PE_aligned:
318 return 0;
320 case DW_EH_PE_textrel:
321 return (_Unwind_Ptr) ob->tbase;
322 case DW_EH_PE_datarel:
323 return (_Unwind_Ptr) ob->dbase;
324 default:
325 gcc_unreachable ();
329 /* Return the FDE pointer encoding from the CIE. */
330 /* ??? This is a subset of extract_cie_info from unwind-dw2.c. */
332 static int
333 get_cie_encoding (const struct dwarf_cie *cie)
335 const unsigned char *aug, *p;
336 _Unwind_Ptr dummy;
337 _uleb128_t utmp;
338 _sleb128_t stmp;
340 aug = cie->augmentation;
341 p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */
342 if (__builtin_expect (cie->version >= 4, 0))
344 if (p[0] != sizeof (void *) || p[1] != 0)
345 return DW_EH_PE_omit; /* We are not prepared to handle unexpected
346 address sizes or segment selectors. */
347 p += 2; /* Skip address size and segment size. */
350 if (aug[0] != 'z')
351 return DW_EH_PE_absptr;
353 p = read_uleb128 (p, &utmp); /* Skip code alignment. */
354 p = read_sleb128 (p, &stmp); /* Skip data alignment. */
355 if (cie->version == 1) /* Skip return address column. */
356 p++;
357 else
358 p = read_uleb128 (p, &utmp);
360 aug++; /* Skip 'z' */
361 p = read_uleb128 (p, &utmp); /* Skip augmentation length. */
362 while (1)
364 /* This is what we're looking for. */
365 if (*aug == 'R')
366 return *p;
367 /* Personality encoding and pointer. */
368 else if (*aug == 'P')
370 /* ??? Avoid dereferencing indirect pointers, since we're
371 faking the base address. Gotta keep DW_EH_PE_aligned
372 intact, however. */
373 p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
375 /* LSDA encoding. */
376 else if (*aug == 'L')
377 p++;
378 /* aarch64 b-key pointer authentication. */
379 else if (*aug == 'B')
380 p++;
381 /* Otherwise end of string, or unknown augmentation. */
382 else
383 return DW_EH_PE_absptr;
384 aug++;
388 static inline int
389 get_fde_encoding (const struct dwarf_fde *f)
391 return get_cie_encoding (get_cie (f));
395 /* Sorting an array of FDEs by address.
396 (Ideally we would have the linker sort the FDEs so we don't have to do
397 it at run time. But the linkers are not yet prepared for this.) */
399 /* Comparison routines. Three variants of increasing complexity. */
401 static int
402 fde_unencoded_compare (struct object *ob __attribute__((unused)),
403 const fde *x, const fde *y)
405 _Unwind_Ptr x_ptr, y_ptr;
406 memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Ptr));
407 memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Ptr));
409 if (x_ptr > y_ptr)
410 return 1;
411 if (x_ptr < y_ptr)
412 return -1;
413 return 0;
416 static int
417 fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
419 _Unwind_Ptr base, x_ptr, y_ptr;
421 base = base_from_object (ob->s.b.encoding, ob);
422 read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
423 read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
425 if (x_ptr > y_ptr)
426 return 1;
427 if (x_ptr < y_ptr)
428 return -1;
429 return 0;
432 static int
433 fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
435 int x_encoding, y_encoding;
436 _Unwind_Ptr x_ptr, y_ptr;
438 x_encoding = get_fde_encoding (x);
439 read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
440 x->pc_begin, &x_ptr);
442 y_encoding = get_fde_encoding (y);
443 read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
444 y->pc_begin, &y_ptr);
446 if (x_ptr > y_ptr)
447 return 1;
448 if (x_ptr < y_ptr)
449 return -1;
450 return 0;
453 typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
455 // The extractor functions compute the pointer values for a block of
456 // fdes. The block processing hides the call overhead.
458 static void
459 fde_unencoded_extract (struct object *ob __attribute__ ((unused)),
460 _Unwind_Ptr *target, const fde **x, int count)
462 for (int index = 0; index < count; ++index)
463 memcpy (target + index, x[index]->pc_begin, sizeof (_Unwind_Ptr));
466 static void
467 fde_single_encoding_extract (struct object *ob, _Unwind_Ptr *target,
468 const fde **x, int count)
470 _Unwind_Ptr base;
472 base = base_from_object (ob->s.b.encoding, ob);
473 for (int index = 0; index < count; ++index)
474 read_encoded_value_with_base (ob->s.b.encoding, base, x[index]->pc_begin,
475 target + index);
478 static void
479 fde_mixed_encoding_extract (struct object *ob, _Unwind_Ptr *target,
480 const fde **x, int count)
482 for (int index = 0; index < count; ++index)
484 int encoding = get_fde_encoding (x[index]);
485 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
486 x[index]->pc_begin, target + index);
490 typedef void (*fde_extractor_t) (struct object *, _Unwind_Ptr *, const fde **,
491 int);
493 // Data is is sorted using radix sort if possible, using an temporary
494 // auxiliary data structure of the same size as the input. When running
495 // out of memory do in-place heap sort.
497 struct fde_accumulator
499 struct fde_vector *linear;
500 struct fde_vector *aux;
503 static inline int
504 start_fde_sort (struct fde_accumulator *accu, size_t count)
506 size_t size;
507 if (! count)
508 return 0;
510 size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
511 if ((accu->linear = malloc (size)))
513 accu->linear->count = 0;
514 if ((accu->aux = malloc (size)))
515 accu->aux->count = 0;
516 return 1;
518 else
519 return 0;
522 static inline void
523 fde_insert (struct fde_accumulator *accu, const fde *this_fde)
525 if (accu->linear)
526 accu->linear->array[accu->linear->count++] = this_fde;
529 #define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
531 /* Convert a semi-heap to a heap. A semi-heap is a heap except possibly
532 for the first (root) node; push it down to its rightful place. */
534 static void
535 frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
536 int lo, int hi)
538 int i, j;
540 for (i = lo, j = 2*i+1;
541 j < hi;
542 j = 2*i+1)
544 if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
545 ++j;
547 if (fde_compare (ob, a[i], a[j]) < 0)
549 SWAP (a[i], a[j]);
550 i = j;
552 else
553 break;
557 /* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must
558 use a name that does not conflict. */
560 static void
561 frame_heapsort (struct object *ob, fde_compare_t fde_compare,
562 struct fde_vector *erratic)
564 /* For a description of this algorithm, see:
565 Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
566 p. 60-61. */
567 const fde ** a = erratic->array;
568 /* A portion of the array is called a "heap" if for all i>=0:
569 If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
570 If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
571 size_t n = erratic->count;
572 int m;
574 /* Expand our heap incrementally from the end of the array, heapifying
575 each resulting semi-heap as we go. After each step, a[m] is the top
576 of a heap. */
577 for (m = n/2-1; m >= 0; --m)
578 frame_downheap (ob, fde_compare, a, m, n);
580 /* Shrink our heap incrementally from the end of the array, first
581 swapping out the largest element a[0] and then re-heapifying the
582 resulting semi-heap. After each step, a[0..m) is a heap. */
583 for (m = n-1; m >= 1; --m)
585 SWAP (a[0], a[m]);
586 frame_downheap (ob, fde_compare, a, 0, m);
588 #undef SWAP
591 // Radix sort data in V1 using V2 as aux memory. Runtime O(n).
592 static inline void
593 fde_radixsort (struct object *ob, fde_extractor_t fde_extractor,
594 struct fde_vector *v1, struct fde_vector *v2)
596 #define FANOUTBITS 8
597 #define FANOUT (1 << FANOUTBITS)
598 #define BLOCKSIZE 128
599 const unsigned rounds
600 = (__CHAR_BIT__ * sizeof (_Unwind_Ptr) + FANOUTBITS - 1) / FANOUTBITS;
601 const fde **a1 = v1->array, **a2 = v2->array;
602 _Unwind_Ptr ptrs[BLOCKSIZE + 1];
603 unsigned n = v1->count;
604 for (unsigned round = 0; round != rounds; ++round)
606 unsigned counts[FANOUT] = {0};
607 unsigned violations = 0;
609 // Count the number of elements per bucket and check if we are already
610 // sorted.
611 _Unwind_Ptr last = 0;
612 for (unsigned i = 0; i < n;)
614 unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
615 fde_extractor (ob, ptrs + 1, a1 + i, chunk);
616 ptrs[0] = last;
617 for (unsigned j = 0; j < chunk; ++j)
619 unsigned b = (ptrs[j + 1] >> (round * FANOUTBITS)) & (FANOUT - 1);
620 counts[b]++;
621 // Use summation instead of an if to eliminate branches.
622 violations += ptrs[j + 1] < ptrs[j];
624 i += chunk;
625 last = ptrs[chunk];
628 // Stop if we are already sorted.
629 if (!violations)
631 // The sorted data is in a1 now.
632 a2 = a1;
633 break;
636 // Compute the prefix sum.
637 unsigned sum = 0;
638 for (unsigned i = 0; i != FANOUT; ++i)
640 unsigned s = sum;
641 sum += counts[i];
642 counts[i] = s;
645 // Place all elements.
646 for (unsigned i = 0; i < n;)
648 unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
649 fde_extractor (ob, ptrs, a1 + i, chunk);
650 for (unsigned j = 0; j < chunk; ++j)
652 unsigned b = (ptrs[j] >> (round * FANOUTBITS)) & (FANOUT - 1);
653 a2[counts[b]++] = a1[i + j];
655 i += chunk;
658 // Swap a1 and a2.
659 const fde **tmp = a1;
660 a1 = a2;
661 a2 = tmp;
663 #undef BLOCKSIZE
664 #undef FANOUT
665 #undef FANOUTBITS
667 // The data is in a2 now, move in place if needed.
668 if (a2 != v1->array)
669 memcpy (v1->array, a2, sizeof (const fde *) * n);
672 static inline void
673 end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
675 gcc_assert (!accu->linear || accu->linear->count == count);
677 if (accu->aux)
679 fde_extractor_t fde_extractor;
680 if (ob->s.b.mixed_encoding)
681 fde_extractor = fde_mixed_encoding_extract;
682 else if (ob->s.b.encoding == DW_EH_PE_absptr)
683 fde_extractor = fde_unencoded_extract;
684 else
685 fde_extractor = fde_single_encoding_extract;
687 fde_radixsort (ob, fde_extractor, accu->linear, accu->aux);
688 free (accu->aux);
690 else
692 fde_compare_t fde_compare;
693 if (ob->s.b.mixed_encoding)
694 fde_compare = fde_mixed_encoding_compare;
695 else if (ob->s.b.encoding == DW_EH_PE_absptr)
696 fde_compare = fde_unencoded_compare;
697 else
698 fde_compare = fde_single_encoding_compare;
700 /* We've not managed to malloc an aux array,
701 so heap sort in the linear one. */
702 frame_heapsort (ob, fde_compare, accu->linear);
706 /* Inspect the fde array beginning at this_fde. This
707 function can be used either in query mode (RANGE is
708 not null, OB is const), or in update mode (RANGE is
709 null, OB is modified). In query mode the function computes
710 the range of PC values and stores it in RANGE. In
711 update mode it updates encoding, mixed_encoding, and pc_begin
712 for OB. Return the number of fdes encountered along the way. */
714 static size_t
715 classify_object_over_fdes (struct object *ob, const fde *this_fde,
716 uintptr_type *range)
718 const struct dwarf_cie *last_cie = 0;
719 size_t count = 0;
720 int encoding = DW_EH_PE_absptr;
721 _Unwind_Ptr base = 0;
723 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
725 const struct dwarf_cie *this_cie;
726 _Unwind_Ptr mask, pc_begin;
728 /* Skip CIEs. */
729 if (this_fde->CIE_delta == 0)
730 continue;
732 /* Determine the encoding for this FDE. Note mixed encoded
733 objects for later. */
734 this_cie = get_cie (this_fde);
735 if (this_cie != last_cie)
737 last_cie = this_cie;
738 encoding = get_cie_encoding (this_cie);
739 if (encoding == DW_EH_PE_omit)
740 return -1;
741 base = base_from_object (encoding, ob);
742 if (!range)
744 if (ob->s.b.encoding == DW_EH_PE_omit)
745 ob->s.b.encoding = encoding;
746 else if (ob->s.b.encoding != encoding)
747 ob->s.b.mixed_encoding = 1;
751 const unsigned char *p;
752 p = read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
753 &pc_begin);
755 /* Take care to ignore link-once functions that were removed.
756 In these cases, the function address will be NULL, but if
757 the encoding is smaller than a pointer a true NULL may not
758 be representable. Assume 0 in the representable bits is NULL. */
759 mask = size_of_encoded_value (encoding);
760 if (mask < sizeof (void *))
761 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
762 else
763 mask = -1;
765 if ((pc_begin & mask) == 0)
766 continue;
768 count += 1;
769 if (range)
771 _Unwind_Ptr pc_range, pc_end;
772 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
773 pc_end = pc_begin + pc_range;
774 if ((!range[0]) && (!range[1]))
776 range[0] = pc_begin;
777 range[1] = pc_end;
779 else
781 if (pc_begin < range[0])
782 range[0] = pc_begin;
783 if (pc_end > range[1])
784 range[1] = pc_end;
787 else
789 if ((void *) pc_begin < ob->pc_begin)
790 ob->pc_begin = (void *) pc_begin;
794 return count;
797 static void
798 add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
800 const struct dwarf_cie *last_cie = 0;
801 int encoding = ob->s.b.encoding;
802 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
804 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
806 const struct dwarf_cie *this_cie;
808 /* Skip CIEs. */
809 if (this_fde->CIE_delta == 0)
810 continue;
812 if (ob->s.b.mixed_encoding)
814 /* Determine the encoding for this FDE. Note mixed encoded
815 objects for later. */
816 this_cie = get_cie (this_fde);
817 if (this_cie != last_cie)
819 last_cie = this_cie;
820 encoding = get_cie_encoding (this_cie);
821 base = base_from_object (encoding, ob);
825 if (encoding == DW_EH_PE_absptr)
827 _Unwind_Ptr ptr;
828 memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Ptr));
829 if (ptr == 0)
830 continue;
832 else
834 _Unwind_Ptr pc_begin, mask;
836 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
837 &pc_begin);
839 /* Take care to ignore link-once functions that were removed.
840 In these cases, the function address will be NULL, but if
841 the encoding is smaller than a pointer a true NULL may not
842 be representable. Assume 0 in the representable bits is NULL. */
843 mask = size_of_encoded_value (encoding);
844 if (mask < sizeof (void *))
845 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
846 else
847 mask = -1;
849 if ((pc_begin & mask) == 0)
850 continue;
853 fde_insert (accu, this_fde);
857 /* Set up a sorted array of pointers to FDEs for a loaded object. We
858 count up the entries before allocating the array because it's likely to
859 be faster. We can be called multiple times, should we have failed to
860 allocate a sorted fde array on a previous occasion. */
862 static inline void
863 init_object (struct object* ob)
865 struct fde_accumulator accu;
866 size_t count;
868 count = ob->s.b.count;
869 if (count == 0)
871 if (ob->s.b.from_array)
873 fde **p = ob->u.array;
874 for (count = 0; *p; ++p)
876 size_t cur_count = classify_object_over_fdes (ob, *p, NULL);
877 if (cur_count == (size_t) -1)
878 goto unhandled_fdes;
879 count += cur_count;
882 else
884 count = classify_object_over_fdes (ob, ob->u.single, NULL);
885 if (count == (size_t) -1)
887 static const fde terminator;
888 unhandled_fdes:
889 ob->s.i = 0;
890 ob->s.b.encoding = DW_EH_PE_omit;
891 ob->u.single = &terminator;
892 return;
896 /* The count field we have in the main struct object is somewhat
897 limited, but should suffice for virtually all cases. If the
898 counted value doesn't fit, re-write a zero. The worst that
899 happens is that we re-count next time -- admittedly non-trivial
900 in that this implies some 2M fdes, but at least we function. */
901 ob->s.b.count = count;
902 if (ob->s.b.count != count)
903 ob->s.b.count = 0;
906 if (!start_fde_sort (&accu, count))
907 return;
909 if (ob->s.b.from_array)
911 fde **p;
912 for (p = ob->u.array; *p; ++p)
913 add_fdes (ob, &accu, *p);
915 else
916 add_fdes (ob, &accu, ob->u.single);
918 end_fde_sort (ob, &accu, count);
920 /* Save the original fde pointer, since this is the key by which the
921 DSO will deregister the object. */
922 accu.linear->orig_data = ob->u.single;
923 ob->u.sort = accu.linear;
925 #ifdef ATOMIC_FDE_FAST_PATH
926 // We must update the sorted bit with an atomic operation
927 struct object tmp;
928 tmp.s.b = ob->s.b;
929 tmp.s.b.sorted = 1;
930 __atomic_store (&(ob->s.b), &(tmp.s.b), __ATOMIC_RELEASE);
931 #else
932 ob->s.b.sorted = 1;
933 #endif
936 #ifdef ATOMIC_FDE_FAST_PATH
937 /* Get the PC range for lookup */
938 static void
939 get_pc_range (const struct object *ob, uintptr_type *range)
941 // It is safe to cast to non-const object* here as
942 // classify_object_over_fdes does not modify ob in query mode.
943 struct object *ncob = (struct object *) (uintptr_type) ob;
944 range[0] = range[1] = 0;
945 if (ob->s.b.sorted)
947 classify_object_over_fdes (ncob, ob->u.sort->orig_data, range);
949 else if (ob->s.b.from_array)
951 fde **p = ob->u.array;
952 for (; *p; ++p)
953 classify_object_over_fdes (ncob, *p, range);
955 else
957 classify_object_over_fdes (ncob, ob->u.single, range);
960 #endif
962 /* A linear search through a set of FDEs for the given PC. This is
963 used when there was insufficient memory to allocate and sort an
964 array. */
966 static const fde *
967 linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
969 const struct dwarf_cie *last_cie = 0;
970 int encoding = ob->s.b.encoding;
971 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
973 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
975 const struct dwarf_cie *this_cie;
976 _Unwind_Ptr pc_begin, pc_range;
978 /* Skip CIEs. */
979 if (this_fde->CIE_delta == 0)
980 continue;
982 if (ob->s.b.mixed_encoding)
984 /* Determine the encoding for this FDE. Note mixed encoded
985 objects for later. */
986 this_cie = get_cie (this_fde);
987 if (this_cie != last_cie)
989 last_cie = this_cie;
990 encoding = get_cie_encoding (this_cie);
991 base = base_from_object (encoding, ob);
995 if (encoding == DW_EH_PE_absptr)
997 const _Unwind_Ptr *pc_array = (const _Unwind_Ptr *) this_fde->pc_begin;
998 pc_begin = pc_array[0];
999 pc_range = pc_array[1];
1000 if (pc_begin == 0)
1001 continue;
1003 else
1005 _Unwind_Ptr mask;
1006 const unsigned char *p;
1008 p = read_encoded_value_with_base (encoding, base,
1009 this_fde->pc_begin, &pc_begin);
1010 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1012 /* Take care to ignore link-once functions that were removed.
1013 In these cases, the function address will be NULL, but if
1014 the encoding is smaller than a pointer a true NULL may not
1015 be representable. Assume 0 in the representable bits is NULL. */
1016 mask = size_of_encoded_value (encoding);
1017 if (mask < sizeof (void *))
1018 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
1019 else
1020 mask = -1;
1022 if ((pc_begin & mask) == 0)
1023 continue;
1026 if ((_Unwind_Ptr) pc - pc_begin < pc_range)
1027 return this_fde;
1030 return NULL;
1033 /* Binary search for an FDE containing the given PC. Here are three
1034 implementations of increasing complexity. */
1036 static inline const fde *
1037 binary_search_unencoded_fdes (struct object *ob, void *pc)
1039 struct fde_vector *vec = ob->u.sort;
1040 size_t lo, hi;
1042 for (lo = 0, hi = vec->count; lo < hi; )
1044 size_t i = (lo + hi) / 2;
1045 const fde *const f = vec->array[i];
1046 void *pc_begin;
1047 uaddr pc_range;
1048 memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *));
1049 memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
1051 if (pc < pc_begin)
1052 hi = i;
1053 else if (pc >= pc_begin + pc_range)
1054 lo = i + 1;
1055 else
1056 return f;
1059 return NULL;
1062 static inline const fde *
1063 binary_search_single_encoding_fdes (struct object *ob, void *pc)
1065 struct fde_vector *vec = ob->u.sort;
1066 int encoding = ob->s.b.encoding;
1067 _Unwind_Ptr base = base_from_object (encoding, ob);
1068 size_t lo, hi;
1070 for (lo = 0, hi = vec->count; lo < hi; )
1072 size_t i = (lo + hi) / 2;
1073 const fde *f = vec->array[i];
1074 _Unwind_Ptr pc_begin, pc_range;
1075 const unsigned char *p;
1077 p = read_encoded_value_with_base (encoding, base, f->pc_begin,
1078 &pc_begin);
1079 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1081 if ((_Unwind_Ptr) pc < pc_begin)
1082 hi = i;
1083 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
1084 lo = i + 1;
1085 else
1086 return f;
1089 return NULL;
1092 static inline const fde *
1093 binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
1095 struct fde_vector *vec = ob->u.sort;
1096 size_t lo, hi;
1098 for (lo = 0, hi = vec->count; lo < hi; )
1100 size_t i = (lo + hi) / 2;
1101 const fde *f = vec->array[i];
1102 _Unwind_Ptr pc_begin, pc_range;
1103 const unsigned char *p;
1104 int encoding;
1106 encoding = get_fde_encoding (f);
1107 p = read_encoded_value_with_base (encoding,
1108 base_from_object (encoding, ob),
1109 f->pc_begin, &pc_begin);
1110 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1112 if ((_Unwind_Ptr) pc < pc_begin)
1113 hi = i;
1114 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
1115 lo = i + 1;
1116 else
1117 return f;
1120 return NULL;
1123 static const fde *
1124 search_object (struct object* ob, void *pc)
1126 /* The fast path initializes objects eagerly to avoid locking.
1127 * On the slow path we initialize them now */
1128 #ifndef ATOMIC_FDE_FAST_PATH
1129 /* If the data hasn't been sorted, try to do this now. We may have
1130 more memory available than last time we tried. */
1131 if (! ob->s.b.sorted)
1133 init_object (ob);
1135 /* Despite the above comment, the normal reason to get here is
1136 that we've not processed this object before. A quick range
1137 check is in order. */
1138 if (pc < ob->pc_begin)
1139 return NULL;
1141 #endif
1143 if (ob->s.b.sorted)
1145 if (ob->s.b.mixed_encoding)
1146 return binary_search_mixed_encoding_fdes (ob, pc);
1147 else if (ob->s.b.encoding == DW_EH_PE_absptr)
1148 return binary_search_unencoded_fdes (ob, pc);
1149 else
1150 return binary_search_single_encoding_fdes (ob, pc);
1152 else
1154 /* Long slow laborious linear search, cos we've no memory. */
1155 if (ob->s.b.from_array)
1157 fde **p;
1158 for (p = ob->u.array; *p ; p++)
1160 const fde *f = linear_search_fdes (ob, *p, pc);
1161 if (f)
1162 return f;
1164 return NULL;
1166 else
1167 return linear_search_fdes (ob, ob->u.single, pc);
1171 #ifdef ATOMIC_FDE_FAST_PATH
1173 // Check if the object was already initialized
1174 static inline bool
1175 is_object_initialized (struct object *ob)
1177 // We have to use acquire atomics for the read, which
1178 // is a bit involved as we read from a bitfield
1179 struct object tmp;
1180 __atomic_load (&(ob->s.b), &(tmp.s.b), __ATOMIC_ACQUIRE);
1181 return tmp.s.b.sorted;
1184 #endif
1186 const fde *
1187 _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
1189 struct object *ob;
1190 const fde *f = NULL;
1192 #ifdef ATOMIC_FDE_FAST_PATH
1193 ob = btree_lookup (&registered_frames, (uintptr_type) pc);
1194 if (!ob)
1195 return NULL;
1197 // Initialize the object lazily
1198 if (!is_object_initialized (ob))
1200 // Check again under mutex
1201 init_object_mutex_once ();
1202 __gthread_mutex_lock (&object_mutex);
1204 if (!ob->s.b.sorted)
1206 init_object (ob);
1209 __gthread_mutex_unlock (&object_mutex);
1212 f = search_object (ob, pc);
1213 #else
1215 init_object_mutex_once ();
1216 __gthread_mutex_lock (&object_mutex);
1218 /* Linear search through the classified objects, to find the one
1219 containing the pc. Note that pc_begin is sorted descending, and
1220 we expect objects to be non-overlapping. */
1221 for (ob = seen_objects; ob; ob = ob->next)
1222 if (pc >= ob->pc_begin)
1224 f = search_object (ob, pc);
1225 if (f)
1226 goto fini;
1227 break;
1230 /* Classify and search the objects we've not yet processed. */
1231 while ((ob = unseen_objects))
1233 struct object **p;
1235 unseen_objects = ob->next;
1236 f = search_object (ob, pc);
1238 /* Insert the object into the classified list. */
1239 for (p = &seen_objects; *p ; p = &(*p)->next)
1240 if ((*p)->pc_begin < ob->pc_begin)
1241 break;
1242 ob->next = *p;
1243 *p = ob;
1245 if (f)
1246 goto fini;
1249 fini:
1250 __gthread_mutex_unlock (&object_mutex);
1251 #endif
1253 if (f)
1255 int encoding;
1256 _Unwind_Ptr func;
1258 bases->tbase = ob->tbase;
1259 bases->dbase = ob->dbase;
1261 encoding = ob->s.b.encoding;
1262 if (ob->s.b.mixed_encoding)
1263 encoding = get_fde_encoding (f);
1264 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
1265 f->pc_begin, &func);
1266 bases->func = (void *) func;
1269 return f;