Daily bump.
[official-gcc.git] / libgcc / unwind-dw2-fde.c
blobeb8f69e6245728981e6ea92e8a2e00ca1321046a
1 /* Subroutines needed for unwinding stack frames for exception handling. */
2 /* Copyright (C) 1997-2024 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 struct btree registered_objects;
52 static bool in_shutdown;
54 static void
55 release_registered_frames (void) __attribute__ ((destructor));
56 static void
57 release_registered_frames (void)
59 /* Release the b-tree and all frames. Frame releases that happen later are
60 * silently ignored */
61 btree_destroy (&registered_frames);
62 btree_destroy (&registered_objects);
63 in_shutdown = true;
66 static void
67 get_pc_range (const struct object *ob, uintptr_type *range);
69 #else
70 /* Without fast path frame deregistration must always succeed. */
71 static const int in_shutdown = 0;
73 /* The unseen_objects list contains objects that have been registered
74 but not yet categorized in any way. The seen_objects list has had
75 its pc_begin and count fields initialized at minimum, and is sorted
76 by decreasing value of pc_begin. */
77 static struct object *unseen_objects;
78 static struct object *seen_objects;
79 #endif
81 #ifdef __GTHREAD_MUTEX_INIT
82 static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
83 #define init_object_mutex_once()
84 #else
85 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
86 static __gthread_mutex_t object_mutex;
88 static void
89 init_object_mutex (void)
91 __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
94 static void
95 init_object_mutex_once (void)
97 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
98 __gthread_once (&once, init_object_mutex);
100 #else
101 /* ??? Several targets include this file with stubbing parts of gthr.h
102 and expect no locking to be done. */
103 #define init_object_mutex_once()
104 static __gthread_mutex_t object_mutex;
105 #endif
106 #endif
108 #ifdef ATOMIC_FDE_FAST_PATH
109 // Register the pc range for a given object in the lookup structure.
110 static void
111 register_pc_range_for_object (uintptr_type begin, struct object *ob)
113 // Register the object itself to know the base pointer on deregistration.
114 btree_insert (&registered_objects, begin, 1, ob);
116 // Register the frame in the b-tree
117 uintptr_type range[2];
118 get_pc_range (ob, range);
119 btree_insert (&registered_frames, range[0], range[1] - range[0], ob);
121 #endif
123 /* Called from crtbegin.o to register the unwind info for an object. */
125 void
126 __register_frame_info_bases (const void *begin, struct object *ob,
127 void *tbase, void *dbase)
129 /* If .eh_frame is empty, don't register at all. */
130 if ((const uword *) begin == 0 || *(const uword *) begin == 0)
131 return;
133 ob->pc_begin = (void *)-1;
134 ob->tbase = tbase;
135 ob->dbase = dbase;
136 ob->u.single = begin;
137 ob->s.i = 0;
138 ob->s.b.encoding = DW_EH_PE_omit;
139 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
140 ob->fde_end = NULL;
141 #endif
143 #ifdef ATOMIC_FDE_FAST_PATH
144 register_pc_range_for_object ((uintptr_type) begin, ob);
145 #else
146 init_object_mutex_once ();
147 __gthread_mutex_lock (&object_mutex);
149 ob->next = unseen_objects;
150 unseen_objects = ob;
152 __gthread_mutex_unlock (&object_mutex);
153 #endif
156 void
157 __register_frame_info (const void *begin, struct object *ob)
159 __register_frame_info_bases (begin, ob, 0, 0);
162 void
163 __register_frame (void *begin)
165 struct object *ob;
167 /* If .eh_frame is empty, don't register at all. */
168 if (*(uword *) begin == 0)
169 return;
171 ob = malloc (sizeof (struct object));
172 __register_frame_info (begin, ob);
175 /* Similar, but BEGIN is actually a pointer to a table of unwind entries
176 for different translation units. Called from the file generated by
177 collect2. */
179 void
180 __register_frame_info_table_bases (void *begin, struct object *ob,
181 void *tbase, void *dbase)
183 ob->pc_begin = (void *)-1;
184 ob->tbase = tbase;
185 ob->dbase = dbase;
186 ob->u.array = begin;
187 ob->s.i = 0;
188 ob->s.b.from_array = 1;
189 ob->s.b.encoding = DW_EH_PE_omit;
191 #ifdef ATOMIC_FDE_FAST_PATH
192 register_pc_range_for_object ((uintptr_type) begin, ob);
193 #else
194 init_object_mutex_once ();
195 __gthread_mutex_lock (&object_mutex);
197 ob->next = unseen_objects;
198 unseen_objects = ob;
200 __gthread_mutex_unlock (&object_mutex);
201 #endif
204 void
205 __register_frame_info_table (void *begin, struct object *ob)
207 __register_frame_info_table_bases (begin, ob, 0, 0);
210 void
211 __register_frame_table (void *begin)
213 struct object *ob = malloc (sizeof (struct object));
214 __register_frame_info_table (begin, ob);
217 /* Called from crtbegin.o to deregister the unwind info for an object. */
218 /* ??? Glibc has for a while now exported __register_frame_info and
219 __deregister_frame_info. If we call __register_frame_info_bases
220 from crtbegin (wherein it is declared weak), and this object does
221 not get pulled from libgcc.a for other reasons, then the
222 invocation of __deregister_frame_info will be resolved from glibc.
223 Since the registration did not happen there, we'll die.
225 Therefore, declare a new deregistration entry point that does the
226 exact same thing, but will resolve to the same library as
227 implements __register_frame_info_bases. */
229 void *
230 __deregister_frame_info_bases (const void *begin)
232 struct object *ob = 0;
234 /* If .eh_frame is empty, we haven't registered. */
235 if ((const uword *) begin == 0 || *(const uword *) begin == 0)
236 return ob;
238 #ifdef ATOMIC_FDE_FAST_PATH
239 // Find the originally registered object to get the base pointer.
240 ob = btree_remove (&registered_objects, (uintptr_type) begin);
242 // Remove the corresponding PC range.
243 if (ob)
245 uintptr_type range[2];
246 get_pc_range (ob, range);
247 if (range[0] != range[1])
248 btree_remove (&registered_frames, range[0]);
251 // Deallocate the sort array if any.
252 if (ob && ob->s.b.sorted)
254 free (ob->u.sort);
256 #else
257 init_object_mutex_once ();
258 __gthread_mutex_lock (&object_mutex);
260 struct object **p;
261 for (p = &unseen_objects; *p ; p = &(*p)->next)
262 if ((*p)->u.single == begin)
264 ob = *p;
265 *p = ob->next;
266 goto out;
269 for (p = &seen_objects; *p ; p = &(*p)->next)
270 if ((*p)->s.b.sorted)
272 if ((*p)->u.sort->orig_data == begin)
274 ob = *p;
275 *p = ob->next;
276 free (ob->u.sort);
277 goto out;
280 else
282 if ((*p)->u.single == begin)
284 ob = *p;
285 *p = ob->next;
286 goto out;
290 out:
291 __gthread_mutex_unlock (&object_mutex);
292 #endif
294 // If we didn't find anything in the lookup data structures then they
295 // were either already destroyed or we tried to remove an empty range.
296 gcc_assert (in_shutdown || ob);
297 return (void *) ob;
300 void *
301 __deregister_frame_info (const void *begin)
303 return __deregister_frame_info_bases (begin);
306 void
307 __deregister_frame (void *begin)
309 /* If .eh_frame is empty, we haven't registered. */
310 if (*(uword *) begin != 0)
311 free (__deregister_frame_info (begin));
315 /* Like base_of_encoded_value, but take the base from a struct object
316 instead of an _Unwind_Context. */
318 static _Unwind_Ptr
319 base_from_object (unsigned char encoding, const struct object *ob)
321 if (encoding == DW_EH_PE_omit)
322 return 0;
324 switch (encoding & 0x70)
326 case DW_EH_PE_absptr:
327 case DW_EH_PE_pcrel:
328 case DW_EH_PE_aligned:
329 return 0;
331 case DW_EH_PE_textrel:
332 return (_Unwind_Ptr) ob->tbase;
333 case DW_EH_PE_datarel:
334 return (_Unwind_Ptr) ob->dbase;
335 default:
336 gcc_unreachable ();
340 /* Return the FDE pointer encoding from the CIE. */
341 /* ??? This is a subset of extract_cie_info from unwind-dw2.c. */
343 static int
344 get_cie_encoding (const struct dwarf_cie *cie)
346 const unsigned char *aug, *p;
347 _Unwind_Ptr dummy;
348 _uleb128_t utmp;
349 _sleb128_t stmp;
351 aug = cie->augmentation;
352 p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */
353 if (__builtin_expect (cie->version >= 4, 0))
355 if (p[0] != sizeof (void *) || p[1] != 0)
356 return DW_EH_PE_omit; /* We are not prepared to handle unexpected
357 address sizes or segment selectors. */
358 p += 2; /* Skip address size and segment size. */
361 if (aug[0] != 'z')
362 return DW_EH_PE_absptr;
364 p = read_uleb128 (p, &utmp); /* Skip code alignment. */
365 p = read_sleb128 (p, &stmp); /* Skip data alignment. */
366 if (cie->version == 1) /* Skip return address column. */
367 p++;
368 else
369 p = read_uleb128 (p, &utmp);
371 aug++; /* Skip 'z' */
372 p = read_uleb128 (p, &utmp); /* Skip augmentation length. */
373 while (1)
375 /* This is what we're looking for. */
376 if (*aug == 'R')
377 return *p;
378 /* Personality encoding and pointer. */
379 else if (*aug == 'P')
381 /* ??? Avoid dereferencing indirect pointers, since we're
382 faking the base address. Gotta keep DW_EH_PE_aligned
383 intact, however. */
384 p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
386 /* LSDA encoding. */
387 else if (*aug == 'L')
388 p++;
389 /* aarch64 b-key pointer authentication. */
390 else if (*aug == 'B')
391 p++;
392 /* Otherwise end of string, or unknown augmentation. */
393 else
394 return DW_EH_PE_absptr;
395 aug++;
399 static inline int
400 get_fde_encoding (const struct dwarf_fde *f)
402 return get_cie_encoding (get_cie (f));
406 /* Sorting an array of FDEs by address.
407 (Ideally we would have the linker sort the FDEs so we don't have to do
408 it at run time. But the linkers are not yet prepared for this.) */
410 /* Comparison routines. Three variants of increasing complexity. */
412 static int
413 fde_unencoded_compare (struct object *ob __attribute__((unused)),
414 const fde *x, const fde *y)
416 _Unwind_Ptr x_ptr, y_ptr;
417 memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Ptr));
418 memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Ptr));
420 if (x_ptr > y_ptr)
421 return 1;
422 if (x_ptr < y_ptr)
423 return -1;
424 return 0;
427 static int
428 fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
430 _Unwind_Ptr base, x_ptr, y_ptr;
432 base = base_from_object (ob->s.b.encoding, ob);
433 read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
434 read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
436 if (x_ptr > y_ptr)
437 return 1;
438 if (x_ptr < y_ptr)
439 return -1;
440 return 0;
443 static int
444 fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
446 int x_encoding, y_encoding;
447 _Unwind_Ptr x_ptr, y_ptr;
449 x_encoding = get_fde_encoding (x);
450 read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
451 x->pc_begin, &x_ptr);
453 y_encoding = get_fde_encoding (y);
454 read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
455 y->pc_begin, &y_ptr);
457 if (x_ptr > y_ptr)
458 return 1;
459 if (x_ptr < y_ptr)
460 return -1;
461 return 0;
464 typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
466 // The extractor functions compute the pointer values for a block of
467 // fdes. The block processing hides the call overhead.
469 static void
470 fde_unencoded_extract (struct object *ob __attribute__ ((unused)),
471 _Unwind_Ptr *target, const fde **x, int count)
473 for (int index = 0; index < count; ++index)
474 memcpy (target + index, x[index]->pc_begin, sizeof (_Unwind_Ptr));
477 static void
478 fde_single_encoding_extract (struct object *ob, _Unwind_Ptr *target,
479 const fde **x, int count)
481 _Unwind_Ptr base;
483 base = base_from_object (ob->s.b.encoding, ob);
484 for (int index = 0; index < count; ++index)
485 read_encoded_value_with_base (ob->s.b.encoding, base, x[index]->pc_begin,
486 target + index);
489 static void
490 fde_mixed_encoding_extract (struct object *ob, _Unwind_Ptr *target,
491 const fde **x, int count)
493 for (int index = 0; index < count; ++index)
495 int encoding = get_fde_encoding (x[index]);
496 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
497 x[index]->pc_begin, target + index);
501 typedef void (*fde_extractor_t) (struct object *, _Unwind_Ptr *, const fde **,
502 int);
504 // Data is sorted using radix sort if possible, using an temporary
505 // auxiliary data structure of the same size as the input. When running
506 // out of memory do in-place heap sort.
508 struct fde_accumulator
510 struct fde_vector *linear;
511 struct fde_vector *aux;
514 static inline int
515 start_fde_sort (struct fde_accumulator *accu, size_t count)
517 size_t size;
518 if (! count)
519 return 0;
521 size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
522 if ((accu->linear = malloc (size)))
524 accu->linear->count = 0;
525 if ((accu->aux = malloc (size)))
526 accu->aux->count = 0;
527 return 1;
529 else
530 return 0;
533 static inline void
534 fde_insert (struct fde_accumulator *accu, const fde *this_fde)
536 if (accu->linear)
537 accu->linear->array[accu->linear->count++] = this_fde;
540 #define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
542 /* Convert a semi-heap to a heap. A semi-heap is a heap except possibly
543 for the first (root) node; push it down to its rightful place. */
545 static void
546 frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
547 int lo, int hi)
549 int i, j;
551 for (i = lo, j = 2*i+1;
552 j < hi;
553 j = 2*i+1)
555 if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
556 ++j;
558 if (fde_compare (ob, a[i], a[j]) < 0)
560 SWAP (a[i], a[j]);
561 i = j;
563 else
564 break;
568 /* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must
569 use a name that does not conflict. */
571 static void
572 frame_heapsort (struct object *ob, fde_compare_t fde_compare,
573 struct fde_vector *erratic)
575 /* For a description of this algorithm, see:
576 Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
577 p. 60-61. */
578 const fde ** a = erratic->array;
579 /* A portion of the array is called a "heap" if for all i>=0:
580 If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
581 If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
582 size_t n = erratic->count;
583 int m;
585 /* Expand our heap incrementally from the end of the array, heapifying
586 each resulting semi-heap as we go. After each step, a[m] is the top
587 of a heap. */
588 for (m = n/2-1; m >= 0; --m)
589 frame_downheap (ob, fde_compare, a, m, n);
591 /* Shrink our heap incrementally from the end of the array, first
592 swapping out the largest element a[0] and then re-heapifying the
593 resulting semi-heap. After each step, a[0..m) is a heap. */
594 for (m = n-1; m >= 1; --m)
596 SWAP (a[0], a[m]);
597 frame_downheap (ob, fde_compare, a, 0, m);
599 #undef SWAP
602 // Radix sort data in V1 using V2 as aux memory. Runtime O(n).
603 static inline void
604 fde_radixsort (struct object *ob, fde_extractor_t fde_extractor,
605 struct fde_vector *v1, struct fde_vector *v2)
607 #define FANOUTBITS 8
608 #define FANOUT (1 << FANOUTBITS)
609 #define BLOCKSIZE 128
610 const unsigned rounds
611 = (__CHAR_BIT__ * sizeof (_Unwind_Ptr) + FANOUTBITS - 1) / FANOUTBITS;
612 const fde **a1 = v1->array, **a2 = v2->array;
613 _Unwind_Ptr ptrs[BLOCKSIZE + 1];
614 unsigned n = v1->count;
615 for (unsigned round = 0; round != rounds; ++round)
617 unsigned counts[FANOUT] = {0};
618 unsigned violations = 0;
620 // Count the number of elements per bucket and check if we are already
621 // sorted.
622 _Unwind_Ptr last = 0;
623 for (unsigned i = 0; i < n;)
625 unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
626 fde_extractor (ob, ptrs + 1, a1 + i, chunk);
627 ptrs[0] = last;
628 for (unsigned j = 0; j < chunk; ++j)
630 unsigned b = (ptrs[j + 1] >> (round * FANOUTBITS)) & (FANOUT - 1);
631 counts[b]++;
632 // Use summation instead of an if to eliminate branches.
633 violations += ptrs[j + 1] < ptrs[j];
635 i += chunk;
636 last = ptrs[chunk];
639 // Stop if we are already sorted.
640 if (!violations)
642 break;
645 // Compute the prefix sum.
646 unsigned sum = 0;
647 for (unsigned i = 0; i != FANOUT; ++i)
649 unsigned s = sum;
650 sum += counts[i];
651 counts[i] = s;
654 // Place all elements.
655 for (unsigned i = 0; i < n;)
657 unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
658 fde_extractor (ob, ptrs, a1 + i, chunk);
659 for (unsigned j = 0; j < chunk; ++j)
661 unsigned b = (ptrs[j] >> (round * FANOUTBITS)) & (FANOUT - 1);
662 a2[counts[b]++] = a1[i + j];
664 i += chunk;
667 // Swap a1 and a2.
668 const fde **tmp = a1;
669 a1 = a2;
670 a2 = tmp;
672 #undef BLOCKSIZE
673 #undef FANOUT
674 #undef FANOUTBITS
676 // The data is in a1 now, move in place if needed.
677 if (a1 != v1->array)
678 memcpy (v1->array, a1, sizeof (const fde *) * n);
681 static inline void
682 end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
684 gcc_assert (!accu->linear || accu->linear->count == count);
686 if (accu->aux)
688 fde_extractor_t fde_extractor;
689 if (ob->s.b.mixed_encoding)
690 fde_extractor = fde_mixed_encoding_extract;
691 else if (ob->s.b.encoding == DW_EH_PE_absptr)
692 fde_extractor = fde_unencoded_extract;
693 else
694 fde_extractor = fde_single_encoding_extract;
696 fde_radixsort (ob, fde_extractor, accu->linear, accu->aux);
697 free (accu->aux);
699 else
701 fde_compare_t fde_compare;
702 if (ob->s.b.mixed_encoding)
703 fde_compare = fde_mixed_encoding_compare;
704 else if (ob->s.b.encoding == DW_EH_PE_absptr)
705 fde_compare = fde_unencoded_compare;
706 else
707 fde_compare = fde_single_encoding_compare;
709 /* We've not managed to malloc an aux array,
710 so heap sort in the linear one. */
711 frame_heapsort (ob, fde_compare, accu->linear);
715 /* Inspect the fde array beginning at this_fde. This
716 function can be used either in query mode (RANGE is
717 not null, OB is const), or in update mode (RANGE is
718 null, OB is modified). In query mode the function computes
719 the range of PC values and stores it in RANGE. In
720 update mode it updates encoding, mixed_encoding, and pc_begin
721 for OB. Return the number of fdes encountered along the way. */
723 static size_t
724 classify_object_over_fdes (struct object *ob, const fde *this_fde,
725 uintptr_type *range)
727 const struct dwarf_cie *last_cie = 0;
728 size_t count = 0;
729 int encoding = DW_EH_PE_absptr;
730 _Unwind_Ptr base = 0;
732 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
734 const struct dwarf_cie *this_cie;
735 _Unwind_Ptr mask, pc_begin;
737 /* Skip CIEs. */
738 if (this_fde->CIE_delta == 0)
739 continue;
741 /* Determine the encoding for this FDE. Note mixed encoded
742 objects for later. */
743 this_cie = get_cie (this_fde);
744 if (this_cie != last_cie)
746 last_cie = this_cie;
747 encoding = get_cie_encoding (this_cie);
748 if (encoding == DW_EH_PE_omit)
749 return -1;
750 base = base_from_object (encoding, ob);
751 if (!range)
753 if (ob->s.b.encoding == DW_EH_PE_omit)
754 ob->s.b.encoding = encoding;
755 else if (ob->s.b.encoding != encoding)
756 ob->s.b.mixed_encoding = 1;
760 const unsigned char *p;
761 p = read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
762 &pc_begin);
764 /* Take care to ignore link-once functions that were removed.
765 In these cases, the function address will be NULL, but if
766 the encoding is smaller than a pointer a true NULL may not
767 be representable. Assume 0 in the representable bits is NULL. */
768 mask = size_of_encoded_value (encoding);
769 if (mask < sizeof (void *))
770 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
771 else
772 mask = -1;
774 if ((pc_begin & mask) == 0)
775 continue;
777 count += 1;
778 if (range)
780 _Unwind_Ptr pc_range, pc_end;
781 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
782 pc_end = pc_begin + pc_range;
783 if ((!range[0]) && (!range[1]))
785 range[0] = pc_begin;
786 range[1] = pc_end;
788 else
790 if (pc_begin < range[0])
791 range[0] = pc_begin;
792 if (pc_end > range[1])
793 range[1] = pc_end;
796 else
798 if ((void *) pc_begin < ob->pc_begin)
799 ob->pc_begin = (void *) pc_begin;
803 return count;
806 static void
807 add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
809 const struct dwarf_cie *last_cie = 0;
810 int encoding = ob->s.b.encoding;
811 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
813 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
815 const struct dwarf_cie *this_cie;
817 /* Skip CIEs. */
818 if (this_fde->CIE_delta == 0)
819 continue;
821 if (ob->s.b.mixed_encoding)
823 /* Determine the encoding for this FDE. Note mixed encoded
824 objects for later. */
825 this_cie = get_cie (this_fde);
826 if (this_cie != last_cie)
828 last_cie = this_cie;
829 encoding = get_cie_encoding (this_cie);
830 base = base_from_object (encoding, ob);
834 if (encoding == DW_EH_PE_absptr)
836 _Unwind_Ptr ptr;
837 memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Ptr));
838 if (ptr == 0)
839 continue;
841 else
843 _Unwind_Ptr pc_begin, mask;
845 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
846 &pc_begin);
848 /* Take care to ignore link-once functions that were removed.
849 In these cases, the function address will be NULL, but if
850 the encoding is smaller than a pointer a true NULL may not
851 be representable. Assume 0 in the representable bits is NULL. */
852 mask = size_of_encoded_value (encoding);
853 if (mask < sizeof (void *))
854 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
855 else
856 mask = -1;
858 if ((pc_begin & mask) == 0)
859 continue;
862 fde_insert (accu, this_fde);
866 /* Set up a sorted array of pointers to FDEs for a loaded object. We
867 count up the entries before allocating the array because it's likely to
868 be faster. We can be called multiple times, should we have failed to
869 allocate a sorted fde array on a previous occasion. */
871 static inline void
872 init_object (struct object* ob)
874 struct fde_accumulator accu;
875 size_t count;
877 count = ob->s.b.count;
878 if (count == 0)
880 if (ob->s.b.from_array)
882 fde **p = ob->u.array;
883 for (count = 0; *p; ++p)
885 size_t cur_count = classify_object_over_fdes (ob, *p, NULL);
886 if (cur_count == (size_t) -1)
887 goto unhandled_fdes;
888 count += cur_count;
891 else
893 count = classify_object_over_fdes (ob, ob->u.single, NULL);
894 if (count == (size_t) -1)
896 static const fde terminator;
897 unhandled_fdes:
898 ob->s.i = 0;
899 ob->s.b.encoding = DW_EH_PE_omit;
900 ob->u.single = &terminator;
901 return;
905 /* The count field we have in the main struct object is somewhat
906 limited, but should suffice for virtually all cases. If the
907 counted value doesn't fit, re-write a zero. The worst that
908 happens is that we re-count next time -- admittedly non-trivial
909 in that this implies some 2M fdes, but at least we function. */
910 ob->s.b.count = count;
911 if (ob->s.b.count != count)
912 ob->s.b.count = 0;
915 if (!start_fde_sort (&accu, count))
916 return;
918 if (ob->s.b.from_array)
920 fde **p;
921 for (p = ob->u.array; *p; ++p)
922 add_fdes (ob, &accu, *p);
924 else
925 add_fdes (ob, &accu, ob->u.single);
927 end_fde_sort (ob, &accu, count);
929 /* Save the original fde pointer, since this is the key by which the
930 DSO will deregister the object. */
931 accu.linear->orig_data = ob->u.single;
932 ob->u.sort = accu.linear;
934 #ifdef ATOMIC_FDE_FAST_PATH
935 // We must update the sorted bit with an atomic operation
936 struct object tmp;
937 tmp.s.b = ob->s.b;
938 tmp.s.b.sorted = 1;
939 __atomic_store (&(ob->s.b), &(tmp.s.b), __ATOMIC_RELEASE);
940 #else
941 ob->s.b.sorted = 1;
942 #endif
945 #ifdef ATOMIC_FDE_FAST_PATH
946 /* Get the PC range for lookup */
947 static void
948 get_pc_range (const struct object *ob, uintptr_type *range)
950 // It is safe to cast to non-const object* here as
951 // classify_object_over_fdes does not modify ob in query mode.
952 struct object *ncob = (struct object *) (uintptr_type) ob;
953 range[0] = range[1] = 0;
954 if (ob->s.b.sorted)
956 classify_object_over_fdes (ncob, ob->u.sort->orig_data, range);
958 else if (ob->s.b.from_array)
960 fde **p = ob->u.array;
961 for (; *p; ++p)
962 classify_object_over_fdes (ncob, *p, range);
964 else
966 classify_object_over_fdes (ncob, ob->u.single, range);
969 #endif
971 /* A linear search through a set of FDEs for the given PC. This is
972 used when there was insufficient memory to allocate and sort an
973 array. */
975 static const fde *
976 linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
978 const struct dwarf_cie *last_cie = 0;
979 int encoding = ob->s.b.encoding;
980 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
982 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
984 const struct dwarf_cie *this_cie;
985 _Unwind_Ptr pc_begin, pc_range;
987 /* Skip CIEs. */
988 if (this_fde->CIE_delta == 0)
989 continue;
991 if (ob->s.b.mixed_encoding)
993 /* Determine the encoding for this FDE. Note mixed encoded
994 objects for later. */
995 this_cie = get_cie (this_fde);
996 if (this_cie != last_cie)
998 last_cie = this_cie;
999 encoding = get_cie_encoding (this_cie);
1000 base = base_from_object (encoding, ob);
1004 if (encoding == DW_EH_PE_absptr)
1006 const _Unwind_Ptr *pc_array = (const _Unwind_Ptr *) this_fde->pc_begin;
1007 pc_begin = pc_array[0];
1008 pc_range = pc_array[1];
1009 if (pc_begin == 0)
1010 continue;
1012 else
1014 _Unwind_Ptr mask;
1015 const unsigned char *p;
1017 p = read_encoded_value_with_base (encoding, base,
1018 this_fde->pc_begin, &pc_begin);
1019 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1021 /* Take care to ignore link-once functions that were removed.
1022 In these cases, the function address will be NULL, but if
1023 the encoding is smaller than a pointer a true NULL may not
1024 be representable. Assume 0 in the representable bits is NULL. */
1025 mask = size_of_encoded_value (encoding);
1026 if (mask < sizeof (void *))
1027 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
1028 else
1029 mask = -1;
1031 if ((pc_begin & mask) == 0)
1032 continue;
1035 if ((_Unwind_Ptr) pc - pc_begin < pc_range)
1036 return this_fde;
1039 return NULL;
1042 /* Binary search for an FDE containing the given PC. Here are three
1043 implementations of increasing complexity. */
1045 static inline const fde *
1046 binary_search_unencoded_fdes (struct object *ob, void *pc)
1048 struct fde_vector *vec = ob->u.sort;
1049 size_t lo, hi;
1051 for (lo = 0, hi = vec->count; lo < hi; )
1053 size_t i = (lo + hi) / 2;
1054 const fde *const f = vec->array[i];
1055 void *pc_begin;
1056 uaddr pc_range;
1057 memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *));
1058 memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
1060 if (pc < pc_begin)
1061 hi = i;
1062 else if (pc >= pc_begin + pc_range)
1063 lo = i + 1;
1064 else
1065 return f;
1068 return NULL;
1071 static inline const fde *
1072 binary_search_single_encoding_fdes (struct object *ob, void *pc)
1074 struct fde_vector *vec = ob->u.sort;
1075 int encoding = ob->s.b.encoding;
1076 _Unwind_Ptr base = base_from_object (encoding, ob);
1077 size_t lo, hi;
1079 for (lo = 0, hi = vec->count; lo < hi; )
1081 size_t i = (lo + hi) / 2;
1082 const fde *f = vec->array[i];
1083 _Unwind_Ptr pc_begin, pc_range;
1084 const unsigned char *p;
1086 p = read_encoded_value_with_base (encoding, base, f->pc_begin,
1087 &pc_begin);
1088 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1090 if ((_Unwind_Ptr) pc < pc_begin)
1091 hi = i;
1092 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
1093 lo = i + 1;
1094 else
1095 return f;
1098 return NULL;
1101 static inline const fde *
1102 binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
1104 struct fde_vector *vec = ob->u.sort;
1105 size_t lo, hi;
1107 for (lo = 0, hi = vec->count; lo < hi; )
1109 size_t i = (lo + hi) / 2;
1110 const fde *f = vec->array[i];
1111 _Unwind_Ptr pc_begin, pc_range;
1112 const unsigned char *p;
1113 int encoding;
1115 encoding = get_fde_encoding (f);
1116 p = read_encoded_value_with_base (encoding,
1117 base_from_object (encoding, ob),
1118 f->pc_begin, &pc_begin);
1119 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1121 if ((_Unwind_Ptr) pc < pc_begin)
1122 hi = i;
1123 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
1124 lo = i + 1;
1125 else
1126 return f;
1129 return NULL;
1132 static const fde *
1133 search_object (struct object* ob, void *pc)
1135 /* The fast path initializes objects eagerly to avoid locking.
1136 * On the slow path we initialize them now */
1137 #ifndef ATOMIC_FDE_FAST_PATH
1138 /* If the data hasn't been sorted, try to do this now. We may have
1139 more memory available than last time we tried. */
1140 if (! ob->s.b.sorted)
1142 init_object (ob);
1144 /* Despite the above comment, the normal reason to get here is
1145 that we've not processed this object before. A quick range
1146 check is in order. */
1147 if (pc < ob->pc_begin)
1148 return NULL;
1150 #endif
1152 if (ob->s.b.sorted)
1154 if (ob->s.b.mixed_encoding)
1155 return binary_search_mixed_encoding_fdes (ob, pc);
1156 else if (ob->s.b.encoding == DW_EH_PE_absptr)
1157 return binary_search_unencoded_fdes (ob, pc);
1158 else
1159 return binary_search_single_encoding_fdes (ob, pc);
1161 else
1163 /* Long slow laborious linear search, cos we've no memory. */
1164 if (ob->s.b.from_array)
1166 fde **p;
1167 for (p = ob->u.array; *p ; p++)
1169 const fde *f = linear_search_fdes (ob, *p, pc);
1170 if (f)
1171 return f;
1173 return NULL;
1175 else
1176 return linear_search_fdes (ob, ob->u.single, pc);
1180 #ifdef ATOMIC_FDE_FAST_PATH
1182 // Check if the object was already initialized
1183 static inline bool
1184 is_object_initialized (struct object *ob)
1186 // We have to use acquire atomics for the read, which
1187 // is a bit involved as we read from a bitfield
1188 struct object tmp;
1189 __atomic_load (&(ob->s.b), &(tmp.s.b), __ATOMIC_ACQUIRE);
1190 return tmp.s.b.sorted;
1193 #endif
1195 const fde *
1196 _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
1198 struct object *ob;
1199 const fde *f = NULL;
1201 #ifdef ATOMIC_FDE_FAST_PATH
1202 ob = btree_lookup (&registered_frames, (uintptr_type) pc);
1203 if (!ob)
1204 return NULL;
1206 // Initialize the object lazily
1207 if (!is_object_initialized (ob))
1209 // Check again under mutex
1210 init_object_mutex_once ();
1211 __gthread_mutex_lock (&object_mutex);
1213 if (!ob->s.b.sorted)
1215 init_object (ob);
1218 __gthread_mutex_unlock (&object_mutex);
1221 f = search_object (ob, pc);
1222 #else
1224 init_object_mutex_once ();
1225 __gthread_mutex_lock (&object_mutex);
1227 /* Linear search through the classified objects, to find the one
1228 containing the pc. Note that pc_begin is sorted descending, and
1229 we expect objects to be non-overlapping. */
1230 for (ob = seen_objects; ob; ob = ob->next)
1231 if (pc >= ob->pc_begin)
1233 f = search_object (ob, pc);
1234 if (f)
1235 goto fini;
1236 break;
1239 /* Classify and search the objects we've not yet processed. */
1240 while ((ob = unseen_objects))
1242 struct object **p;
1244 unseen_objects = ob->next;
1245 f = search_object (ob, pc);
1247 /* Insert the object into the classified list. */
1248 for (p = &seen_objects; *p ; p = &(*p)->next)
1249 if ((*p)->pc_begin < ob->pc_begin)
1250 break;
1251 ob->next = *p;
1252 *p = ob;
1254 if (f)
1255 goto fini;
1258 fini:
1259 __gthread_mutex_unlock (&object_mutex);
1260 #endif
1262 if (f)
1264 int encoding;
1265 _Unwind_Ptr func;
1267 bases->tbase = ob->tbase;
1268 bases->dbase = ob->dbase;
1270 encoding = ob->s.b.encoding;
1271 if (ob->s.b.mixed_encoding)
1272 encoding = get_fde_encoding (f);
1273 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
1274 f->pc_begin, &func);
1275 bases->func = (void *) func;
1278 return f;