]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/unwind-dw2-fde.c
release the sorted FDE array when deregistering a frame [PR109685]
[thirdparty/gcc.git] / libgcc / unwind-dw2-fde.c
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>.
4
5 This file is part of GCC.
6
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.
11
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.
16
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.
20
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/>. */
25
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
44
45 typedef __UINTPTR_TYPE__ uintptr_type;
46
47 #ifdef ATOMIC_FDE_FAST_PATH
48 #include "unwind-dw2-btree.h"
49
50 static struct btree registered_frames;
51 static bool in_shutdown;
52
53 static void
54 release_registered_frames (void) __attribute__ ((destructor));
55 static void
56 release_registered_frames (void)
57 {
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;
62 }
63
64 static void
65 get_pc_range (const struct object *ob, uintptr_type *range);
66
67 #else
68 /* Without fast path frame deregistration must always succeed. */
69 static const int in_shutdown = 0;
70
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
78
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;
85
86 static void
87 init_object_mutex (void)
88 {
89 __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
90 }
91
92 static void
93 init_object_mutex_once (void)
94 {
95 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
96 __gthread_once (&once, init_object_mutex);
97 }
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
105
106 /* Called from crtbegin.o to register the unwind info for an object. */
107
108 void
109 __register_frame_info_bases (const void *begin, struct object *ob,
110 void *tbase, void *dbase)
111 {
112 /* If .eh_frame is empty, don't register at all. */
113 if ((const uword *) begin == 0 || *(const uword *) begin == 0)
114 return;
115
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
125
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);
134
135 ob->next = unseen_objects;
136 unseen_objects = ob;
137
138 __gthread_mutex_unlock (&object_mutex);
139 #endif
140 }
141
142 void
143 __register_frame_info (const void *begin, struct object *ob)
144 {
145 __register_frame_info_bases (begin, ob, 0, 0);
146 }
147
148 void
149 __register_frame (void *begin)
150 {
151 struct object *ob;
152
153 /* If .eh_frame is empty, don't register at all. */
154 if (*(uword *) begin == 0)
155 return;
156
157 ob = malloc (sizeof (struct object));
158 __register_frame_info (begin, ob);
159 }
160
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. */
164
165 void
166 __register_frame_info_table_bases (void *begin, struct object *ob,
167 void *tbase, void *dbase)
168 {
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;
176
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);
185
186 ob->next = unseen_objects;
187 unseen_objects = ob;
188
189 __gthread_mutex_unlock (&object_mutex);
190 #endif
191 }
192
193 void
194 __register_frame_info_table (void *begin, struct object *ob)
195 {
196 __register_frame_info_table_bases (begin, ob, 0, 0);
197 }
198
199 void
200 __register_frame_table (void *begin)
201 {
202 struct object *ob = malloc (sizeof (struct object));
203 __register_frame_info_table (begin, ob);
204 }
205
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.
213
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. */
217
218 void *
219 __deregister_frame_info_bases (const void *begin)
220 {
221 struct object *ob = 0;
222
223 /* If .eh_frame is empty, we haven't registered. */
224 if ((const uword *) begin == 0 || *(const uword *) begin == 0)
225 return ob;
226
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);
240
241 // And remove
242 ob = btree_remove (&registered_frames, range[0]);
243 bool empty_table = (range[1] - range[0]) == 0;
244
245 // Deallocate the sort array if any.
246 if (ob && ob->s.b.sorted)
247 {
248 free (ob->u.sort);
249 }
250 #else
251 init_object_mutex_once ();
252 __gthread_mutex_lock (&object_mutex);
253
254 struct object **p;
255 for (p = &unseen_objects; *p ; p = &(*p)->next)
256 if ((*p)->u.single == begin)
257 {
258 ob = *p;
259 *p = ob->next;
260 goto out;
261 }
262
263 for (p = &seen_objects; *p ; p = &(*p)->next)
264 if ((*p)->s.b.sorted)
265 {
266 if ((*p)->u.sort->orig_data == begin)
267 {
268 ob = *p;
269 *p = ob->next;
270 free (ob->u.sort);
271 goto out;
272 }
273 }
274 else
275 {
276 if ((*p)->u.single == begin)
277 {
278 ob = *p;
279 *p = ob->next;
280 goto out;
281 }
282 }
283
284 out:
285 __gthread_mutex_unlock (&object_mutex);
286 const int empty_table = 0; // The non-atomic path stores all tables.
287 #endif
288
289 // If we didn't find anything in the lookup data structures then they
290 // were either already destroyed or we tried to remove an empty range.
291 gcc_assert (in_shutdown || (empty_table || ob));
292 return (void *) ob;
293 }
294
295 void *
296 __deregister_frame_info (const void *begin)
297 {
298 return __deregister_frame_info_bases (begin);
299 }
300
301 void
302 __deregister_frame (void *begin)
303 {
304 /* If .eh_frame is empty, we haven't registered. */
305 if (*(uword *) begin != 0)
306 free (__deregister_frame_info (begin));
307 }
308
309 \f
310 /* Like base_of_encoded_value, but take the base from a struct object
311 instead of an _Unwind_Context. */
312
313 static _Unwind_Ptr
314 base_from_object (unsigned char encoding, const struct object *ob)
315 {
316 if (encoding == DW_EH_PE_omit)
317 return 0;
318
319 switch (encoding & 0x70)
320 {
321 case DW_EH_PE_absptr:
322 case DW_EH_PE_pcrel:
323 case DW_EH_PE_aligned:
324 return 0;
325
326 case DW_EH_PE_textrel:
327 return (_Unwind_Ptr) ob->tbase;
328 case DW_EH_PE_datarel:
329 return (_Unwind_Ptr) ob->dbase;
330 default:
331 gcc_unreachable ();
332 }
333 }
334
335 /* Return the FDE pointer encoding from the CIE. */
336 /* ??? This is a subset of extract_cie_info from unwind-dw2.c. */
337
338 static int
339 get_cie_encoding (const struct dwarf_cie *cie)
340 {
341 const unsigned char *aug, *p;
342 _Unwind_Ptr dummy;
343 _uleb128_t utmp;
344 _sleb128_t stmp;
345
346 aug = cie->augmentation;
347 p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */
348 if (__builtin_expect (cie->version >= 4, 0))
349 {
350 if (p[0] != sizeof (void *) || p[1] != 0)
351 return DW_EH_PE_omit; /* We are not prepared to handle unexpected
352 address sizes or segment selectors. */
353 p += 2; /* Skip address size and segment size. */
354 }
355
356 if (aug[0] != 'z')
357 return DW_EH_PE_absptr;
358
359 p = read_uleb128 (p, &utmp); /* Skip code alignment. */
360 p = read_sleb128 (p, &stmp); /* Skip data alignment. */
361 if (cie->version == 1) /* Skip return address column. */
362 p++;
363 else
364 p = read_uleb128 (p, &utmp);
365
366 aug++; /* Skip 'z' */
367 p = read_uleb128 (p, &utmp); /* Skip augmentation length. */
368 while (1)
369 {
370 /* This is what we're looking for. */
371 if (*aug == 'R')
372 return *p;
373 /* Personality encoding and pointer. */
374 else if (*aug == 'P')
375 {
376 /* ??? Avoid dereferencing indirect pointers, since we're
377 faking the base address. Gotta keep DW_EH_PE_aligned
378 intact, however. */
379 p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
380 }
381 /* LSDA encoding. */
382 else if (*aug == 'L')
383 p++;
384 /* aarch64 b-key pointer authentication. */
385 else if (*aug == 'B')
386 p++;
387 /* Otherwise end of string, or unknown augmentation. */
388 else
389 return DW_EH_PE_absptr;
390 aug++;
391 }
392 }
393
394 static inline int
395 get_fde_encoding (const struct dwarf_fde *f)
396 {
397 return get_cie_encoding (get_cie (f));
398 }
399
400 \f
401 /* Sorting an array of FDEs by address.
402 (Ideally we would have the linker sort the FDEs so we don't have to do
403 it at run time. But the linkers are not yet prepared for this.) */
404
405 /* Comparison routines. Three variants of increasing complexity. */
406
407 static int
408 fde_unencoded_compare (struct object *ob __attribute__((unused)),
409 const fde *x, const fde *y)
410 {
411 _Unwind_Ptr x_ptr, y_ptr;
412 memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Ptr));
413 memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Ptr));
414
415 if (x_ptr > y_ptr)
416 return 1;
417 if (x_ptr < y_ptr)
418 return -1;
419 return 0;
420 }
421
422 static int
423 fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
424 {
425 _Unwind_Ptr base, x_ptr, y_ptr;
426
427 base = base_from_object (ob->s.b.encoding, ob);
428 read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
429 read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
430
431 if (x_ptr > y_ptr)
432 return 1;
433 if (x_ptr < y_ptr)
434 return -1;
435 return 0;
436 }
437
438 static int
439 fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
440 {
441 int x_encoding, y_encoding;
442 _Unwind_Ptr x_ptr, y_ptr;
443
444 x_encoding = get_fde_encoding (x);
445 read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
446 x->pc_begin, &x_ptr);
447
448 y_encoding = get_fde_encoding (y);
449 read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
450 y->pc_begin, &y_ptr);
451
452 if (x_ptr > y_ptr)
453 return 1;
454 if (x_ptr < y_ptr)
455 return -1;
456 return 0;
457 }
458
459 typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
460
461 // The extractor functions compute the pointer values for a block of
462 // fdes. The block processing hides the call overhead.
463
464 static void
465 fde_unencoded_extract (struct object *ob __attribute__ ((unused)),
466 _Unwind_Ptr *target, const fde **x, int count)
467 {
468 for (int index = 0; index < count; ++index)
469 memcpy (target + index, x[index]->pc_begin, sizeof (_Unwind_Ptr));
470 }
471
472 static void
473 fde_single_encoding_extract (struct object *ob, _Unwind_Ptr *target,
474 const fde **x, int count)
475 {
476 _Unwind_Ptr base;
477
478 base = base_from_object (ob->s.b.encoding, ob);
479 for (int index = 0; index < count; ++index)
480 read_encoded_value_with_base (ob->s.b.encoding, base, x[index]->pc_begin,
481 target + index);
482 }
483
484 static void
485 fde_mixed_encoding_extract (struct object *ob, _Unwind_Ptr *target,
486 const fde **x, int count)
487 {
488 for (int index = 0; index < count; ++index)
489 {
490 int encoding = get_fde_encoding (x[index]);
491 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
492 x[index]->pc_begin, target + index);
493 }
494 }
495
496 typedef void (*fde_extractor_t) (struct object *, _Unwind_Ptr *, const fde **,
497 int);
498
499 // Data is is sorted using radix sort if possible, using an temporary
500 // auxiliary data structure of the same size as the input. When running
501 // out of memory do in-place heap sort.
502
503 struct fde_accumulator
504 {
505 struct fde_vector *linear;
506 struct fde_vector *aux;
507 };
508
509 static inline int
510 start_fde_sort (struct fde_accumulator *accu, size_t count)
511 {
512 size_t size;
513 if (! count)
514 return 0;
515
516 size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
517 if ((accu->linear = malloc (size)))
518 {
519 accu->linear->count = 0;
520 if ((accu->aux = malloc (size)))
521 accu->aux->count = 0;
522 return 1;
523 }
524 else
525 return 0;
526 }
527
528 static inline void
529 fde_insert (struct fde_accumulator *accu, const fde *this_fde)
530 {
531 if (accu->linear)
532 accu->linear->array[accu->linear->count++] = this_fde;
533 }
534
535 #define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
536
537 /* Convert a semi-heap to a heap. A semi-heap is a heap except possibly
538 for the first (root) node; push it down to its rightful place. */
539
540 static void
541 frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
542 int lo, int hi)
543 {
544 int i, j;
545
546 for (i = lo, j = 2*i+1;
547 j < hi;
548 j = 2*i+1)
549 {
550 if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
551 ++j;
552
553 if (fde_compare (ob, a[i], a[j]) < 0)
554 {
555 SWAP (a[i], a[j]);
556 i = j;
557 }
558 else
559 break;
560 }
561 }
562
563 /* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must
564 use a name that does not conflict. */
565
566 static void
567 frame_heapsort (struct object *ob, fde_compare_t fde_compare,
568 struct fde_vector *erratic)
569 {
570 /* For a description of this algorithm, see:
571 Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
572 p. 60-61. */
573 const fde ** a = erratic->array;
574 /* A portion of the array is called a "heap" if for all i>=0:
575 If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
576 If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
577 size_t n = erratic->count;
578 int m;
579
580 /* Expand our heap incrementally from the end of the array, heapifying
581 each resulting semi-heap as we go. After each step, a[m] is the top
582 of a heap. */
583 for (m = n/2-1; m >= 0; --m)
584 frame_downheap (ob, fde_compare, a, m, n);
585
586 /* Shrink our heap incrementally from the end of the array, first
587 swapping out the largest element a[0] and then re-heapifying the
588 resulting semi-heap. After each step, a[0..m) is a heap. */
589 for (m = n-1; m >= 1; --m)
590 {
591 SWAP (a[0], a[m]);
592 frame_downheap (ob, fde_compare, a, 0, m);
593 }
594 #undef SWAP
595 }
596
597 // Radix sort data in V1 using V2 as aux memory. Runtime O(n).
598 static inline void
599 fde_radixsort (struct object *ob, fde_extractor_t fde_extractor,
600 struct fde_vector *v1, struct fde_vector *v2)
601 {
602 #define FANOUTBITS 8
603 #define FANOUT (1 << FANOUTBITS)
604 #define BLOCKSIZE 128
605 const unsigned rounds
606 = (__CHAR_BIT__ * sizeof (_Unwind_Ptr) + FANOUTBITS - 1) / FANOUTBITS;
607 const fde **a1 = v1->array, **a2 = v2->array;
608 _Unwind_Ptr ptrs[BLOCKSIZE + 1];
609 unsigned n = v1->count;
610 for (unsigned round = 0; round != rounds; ++round)
611 {
612 unsigned counts[FANOUT] = {0};
613 unsigned violations = 0;
614
615 // Count the number of elements per bucket and check if we are already
616 // sorted.
617 _Unwind_Ptr last = 0;
618 for (unsigned i = 0; i < n;)
619 {
620 unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
621 fde_extractor (ob, ptrs + 1, a1 + i, chunk);
622 ptrs[0] = last;
623 for (unsigned j = 0; j < chunk; ++j)
624 {
625 unsigned b = (ptrs[j + 1] >> (round * FANOUTBITS)) & (FANOUT - 1);
626 counts[b]++;
627 // Use summation instead of an if to eliminate branches.
628 violations += ptrs[j + 1] < ptrs[j];
629 }
630 i += chunk;
631 last = ptrs[chunk];
632 }
633
634 // Stop if we are already sorted.
635 if (!violations)
636 {
637 // The sorted data is in a1 now.
638 a2 = a1;
639 break;
640 }
641
642 // Compute the prefix sum.
643 unsigned sum = 0;
644 for (unsigned i = 0; i != FANOUT; ++i)
645 {
646 unsigned s = sum;
647 sum += counts[i];
648 counts[i] = s;
649 }
650
651 // Place all elements.
652 for (unsigned i = 0; i < n;)
653 {
654 unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
655 fde_extractor (ob, ptrs, a1 + i, chunk);
656 for (unsigned j = 0; j < chunk; ++j)
657 {
658 unsigned b = (ptrs[j] >> (round * FANOUTBITS)) & (FANOUT - 1);
659 a2[counts[b]++] = a1[i + j];
660 }
661 i += chunk;
662 }
663
664 // Swap a1 and a2.
665 const fde **tmp = a1;
666 a1 = a2;
667 a2 = tmp;
668 }
669 #undef BLOCKSIZE
670 #undef FANOUT
671 #undef FANOUTBITS
672
673 // The data is in a2 now, move in place if needed.
674 if (a2 != v1->array)
675 memcpy (v1->array, a2, sizeof (const fde *) * n);
676 }
677
678 static inline void
679 end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
680 {
681 gcc_assert (!accu->linear || accu->linear->count == count);
682
683 if (accu->aux)
684 {
685 fde_extractor_t fde_extractor;
686 if (ob->s.b.mixed_encoding)
687 fde_extractor = fde_mixed_encoding_extract;
688 else if (ob->s.b.encoding == DW_EH_PE_absptr)
689 fde_extractor = fde_unencoded_extract;
690 else
691 fde_extractor = fde_single_encoding_extract;
692
693 fde_radixsort (ob, fde_extractor, accu->linear, accu->aux);
694 free (accu->aux);
695 }
696 else
697 {
698 fde_compare_t fde_compare;
699 if (ob->s.b.mixed_encoding)
700 fde_compare = fde_mixed_encoding_compare;
701 else if (ob->s.b.encoding == DW_EH_PE_absptr)
702 fde_compare = fde_unencoded_compare;
703 else
704 fde_compare = fde_single_encoding_compare;
705
706 /* We've not managed to malloc an aux array,
707 so heap sort in the linear one. */
708 frame_heapsort (ob, fde_compare, accu->linear);
709 }
710 }
711
712 /* Inspect the fde array beginning at this_fde. This
713 function can be used either in query mode (RANGE is
714 not null, OB is const), or in update mode (RANGE is
715 null, OB is modified). In query mode the function computes
716 the range of PC values and stores it in RANGE. In
717 update mode it updates encoding, mixed_encoding, and pc_begin
718 for OB. Return the number of fdes encountered along the way. */
719
720 static size_t
721 classify_object_over_fdes (struct object *ob, const fde *this_fde,
722 uintptr_type *range)
723 {
724 const struct dwarf_cie *last_cie = 0;
725 size_t count = 0;
726 int encoding = DW_EH_PE_absptr;
727 _Unwind_Ptr base = 0;
728
729 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
730 {
731 const struct dwarf_cie *this_cie;
732 _Unwind_Ptr mask, pc_begin;
733
734 /* Skip CIEs. */
735 if (this_fde->CIE_delta == 0)
736 continue;
737
738 /* Determine the encoding for this FDE. Note mixed encoded
739 objects for later. */
740 this_cie = get_cie (this_fde);
741 if (this_cie != last_cie)
742 {
743 last_cie = this_cie;
744 encoding = get_cie_encoding (this_cie);
745 if (encoding == DW_EH_PE_omit)
746 return -1;
747 base = base_from_object (encoding, ob);
748 if (!range)
749 {
750 if (ob->s.b.encoding == DW_EH_PE_omit)
751 ob->s.b.encoding = encoding;
752 else if (ob->s.b.encoding != encoding)
753 ob->s.b.mixed_encoding = 1;
754 }
755 }
756
757 const unsigned char *p;
758 p = read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
759 &pc_begin);
760
761 /* Take care to ignore link-once functions that were removed.
762 In these cases, the function address will be NULL, but if
763 the encoding is smaller than a pointer a true NULL may not
764 be representable. Assume 0 in the representable bits is NULL. */
765 mask = size_of_encoded_value (encoding);
766 if (mask < sizeof (void *))
767 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
768 else
769 mask = -1;
770
771 if ((pc_begin & mask) == 0)
772 continue;
773
774 count += 1;
775 if (range)
776 {
777 _Unwind_Ptr pc_range, pc_end;
778 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
779 pc_end = pc_begin + pc_range;
780 if ((!range[0]) && (!range[1]))
781 {
782 range[0] = pc_begin;
783 range[1] = pc_end;
784 }
785 else
786 {
787 if (pc_begin < range[0])
788 range[0] = pc_begin;
789 if (pc_end > range[1])
790 range[1] = pc_end;
791 }
792 }
793 else
794 {
795 if ((void *) pc_begin < ob->pc_begin)
796 ob->pc_begin = (void *) pc_begin;
797 }
798 }
799
800 return count;
801 }
802
803 static void
804 add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
805 {
806 const struct dwarf_cie *last_cie = 0;
807 int encoding = ob->s.b.encoding;
808 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
809
810 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
811 {
812 const struct dwarf_cie *this_cie;
813
814 /* Skip CIEs. */
815 if (this_fde->CIE_delta == 0)
816 continue;
817
818 if (ob->s.b.mixed_encoding)
819 {
820 /* Determine the encoding for this FDE. Note mixed encoded
821 objects for later. */
822 this_cie = get_cie (this_fde);
823 if (this_cie != last_cie)
824 {
825 last_cie = this_cie;
826 encoding = get_cie_encoding (this_cie);
827 base = base_from_object (encoding, ob);
828 }
829 }
830
831 if (encoding == DW_EH_PE_absptr)
832 {
833 _Unwind_Ptr ptr;
834 memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Ptr));
835 if (ptr == 0)
836 continue;
837 }
838 else
839 {
840 _Unwind_Ptr pc_begin, mask;
841
842 read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
843 &pc_begin);
844
845 /* Take care to ignore link-once functions that were removed.
846 In these cases, the function address will be NULL, but if
847 the encoding is smaller than a pointer a true NULL may not
848 be representable. Assume 0 in the representable bits is NULL. */
849 mask = size_of_encoded_value (encoding);
850 if (mask < sizeof (void *))
851 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
852 else
853 mask = -1;
854
855 if ((pc_begin & mask) == 0)
856 continue;
857 }
858
859 fde_insert (accu, this_fde);
860 }
861 }
862
863 /* Set up a sorted array of pointers to FDEs for a loaded object. We
864 count up the entries before allocating the array because it's likely to
865 be faster. We can be called multiple times, should we have failed to
866 allocate a sorted fde array on a previous occasion. */
867
868 static inline void
869 init_object (struct object* ob)
870 {
871 struct fde_accumulator accu;
872 size_t count;
873
874 count = ob->s.b.count;
875 if (count == 0)
876 {
877 if (ob->s.b.from_array)
878 {
879 fde **p = ob->u.array;
880 for (count = 0; *p; ++p)
881 {
882 size_t cur_count = classify_object_over_fdes (ob, *p, NULL);
883 if (cur_count == (size_t) -1)
884 goto unhandled_fdes;
885 count += cur_count;
886 }
887 }
888 else
889 {
890 count = classify_object_over_fdes (ob, ob->u.single, NULL);
891 if (count == (size_t) -1)
892 {
893 static const fde terminator;
894 unhandled_fdes:
895 ob->s.i = 0;
896 ob->s.b.encoding = DW_EH_PE_omit;
897 ob->u.single = &terminator;
898 return;
899 }
900 }
901
902 /* The count field we have in the main struct object is somewhat
903 limited, but should suffice for virtually all cases. If the
904 counted value doesn't fit, re-write a zero. The worst that
905 happens is that we re-count next time -- admittedly non-trivial
906 in that this implies some 2M fdes, but at least we function. */
907 ob->s.b.count = count;
908 if (ob->s.b.count != count)
909 ob->s.b.count = 0;
910 }
911
912 if (!start_fde_sort (&accu, count))
913 return;
914
915 if (ob->s.b.from_array)
916 {
917 fde **p;
918 for (p = ob->u.array; *p; ++p)
919 add_fdes (ob, &accu, *p);
920 }
921 else
922 add_fdes (ob, &accu, ob->u.single);
923
924 end_fde_sort (ob, &accu, count);
925
926 /* Save the original fde pointer, since this is the key by which the
927 DSO will deregister the object. */
928 accu.linear->orig_data = ob->u.single;
929 ob->u.sort = accu.linear;
930
931 #ifdef ATOMIC_FDE_FAST_PATH
932 // We must update the sorted bit with an atomic operation
933 struct object tmp;
934 tmp.s.b = ob->s.b;
935 tmp.s.b.sorted = 1;
936 __atomic_store (&(ob->s.b), &(tmp.s.b), __ATOMIC_RELEASE);
937 #else
938 ob->s.b.sorted = 1;
939 #endif
940 }
941
942 #ifdef ATOMIC_FDE_FAST_PATH
943 /* Get the PC range for lookup */
944 static void
945 get_pc_range (const struct object *ob, uintptr_type *range)
946 {
947 // It is safe to cast to non-const object* here as
948 // classify_object_over_fdes does not modify ob in query mode.
949 struct object *ncob = (struct object *) (uintptr_type) ob;
950 range[0] = range[1] = 0;
951 if (ob->s.b.sorted)
952 {
953 classify_object_over_fdes (ncob, ob->u.sort->orig_data, range);
954 }
955 else if (ob->s.b.from_array)
956 {
957 fde **p = ob->u.array;
958 for (; *p; ++p)
959 classify_object_over_fdes (ncob, *p, range);
960 }
961 else
962 {
963 classify_object_over_fdes (ncob, ob->u.single, range);
964 }
965 }
966 #endif
967
968 /* A linear search through a set of FDEs for the given PC. This is
969 used when there was insufficient memory to allocate and sort an
970 array. */
971
972 static const fde *
973 linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
974 {
975 const struct dwarf_cie *last_cie = 0;
976 int encoding = ob->s.b.encoding;
977 _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
978
979 for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
980 {
981 const struct dwarf_cie *this_cie;
982 _Unwind_Ptr pc_begin, pc_range;
983
984 /* Skip CIEs. */
985 if (this_fde->CIE_delta == 0)
986 continue;
987
988 if (ob->s.b.mixed_encoding)
989 {
990 /* Determine the encoding for this FDE. Note mixed encoded
991 objects for later. */
992 this_cie = get_cie (this_fde);
993 if (this_cie != last_cie)
994 {
995 last_cie = this_cie;
996 encoding = get_cie_encoding (this_cie);
997 base = base_from_object (encoding, ob);
998 }
999 }
1000
1001 if (encoding == DW_EH_PE_absptr)
1002 {
1003 const _Unwind_Ptr *pc_array = (const _Unwind_Ptr *) this_fde->pc_begin;
1004 pc_begin = pc_array[0];
1005 pc_range = pc_array[1];
1006 if (pc_begin == 0)
1007 continue;
1008 }
1009 else
1010 {
1011 _Unwind_Ptr mask;
1012 const unsigned char *p;
1013
1014 p = read_encoded_value_with_base (encoding, base,
1015 this_fde->pc_begin, &pc_begin);
1016 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1017
1018 /* Take care to ignore link-once functions that were removed.
1019 In these cases, the function address will be NULL, but if
1020 the encoding is smaller than a pointer a true NULL may not
1021 be representable. Assume 0 in the representable bits is NULL. */
1022 mask = size_of_encoded_value (encoding);
1023 if (mask < sizeof (void *))
1024 mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
1025 else
1026 mask = -1;
1027
1028 if ((pc_begin & mask) == 0)
1029 continue;
1030 }
1031
1032 if ((_Unwind_Ptr) pc - pc_begin < pc_range)
1033 return this_fde;
1034 }
1035
1036 return NULL;
1037 }
1038
1039 /* Binary search for an FDE containing the given PC. Here are three
1040 implementations of increasing complexity. */
1041
1042 static inline const fde *
1043 binary_search_unencoded_fdes (struct object *ob, void *pc)
1044 {
1045 struct fde_vector *vec = ob->u.sort;
1046 size_t lo, hi;
1047
1048 for (lo = 0, hi = vec->count; lo < hi; )
1049 {
1050 size_t i = (lo + hi) / 2;
1051 const fde *const f = vec->array[i];
1052 void *pc_begin;
1053 uaddr pc_range;
1054 memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *));
1055 memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
1056
1057 if (pc < pc_begin)
1058 hi = i;
1059 else if (pc >= pc_begin + pc_range)
1060 lo = i + 1;
1061 else
1062 return f;
1063 }
1064
1065 return NULL;
1066 }
1067
1068 static inline const fde *
1069 binary_search_single_encoding_fdes (struct object *ob, void *pc)
1070 {
1071 struct fde_vector *vec = ob->u.sort;
1072 int encoding = ob->s.b.encoding;
1073 _Unwind_Ptr base = base_from_object (encoding, ob);
1074 size_t lo, hi;
1075
1076 for (lo = 0, hi = vec->count; lo < hi; )
1077 {
1078 size_t i = (lo + hi) / 2;
1079 const fde *f = vec->array[i];
1080 _Unwind_Ptr pc_begin, pc_range;
1081 const unsigned char *p;
1082
1083 p = read_encoded_value_with_base (encoding, base, f->pc_begin,
1084 &pc_begin);
1085 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1086
1087 if ((_Unwind_Ptr) pc < pc_begin)
1088 hi = i;
1089 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
1090 lo = i + 1;
1091 else
1092 return f;
1093 }
1094
1095 return NULL;
1096 }
1097
1098 static inline const fde *
1099 binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
1100 {
1101 struct fde_vector *vec = ob->u.sort;
1102 size_t lo, hi;
1103
1104 for (lo = 0, hi = vec->count; lo < hi; )
1105 {
1106 size_t i = (lo + hi) / 2;
1107 const fde *f = vec->array[i];
1108 _Unwind_Ptr pc_begin, pc_range;
1109 const unsigned char *p;
1110 int encoding;
1111
1112 encoding = get_fde_encoding (f);
1113 p = read_encoded_value_with_base (encoding,
1114 base_from_object (encoding, ob),
1115 f->pc_begin, &pc_begin);
1116 read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
1117
1118 if ((_Unwind_Ptr) pc < pc_begin)
1119 hi = i;
1120 else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
1121 lo = i + 1;
1122 else
1123 return f;
1124 }
1125
1126 return NULL;
1127 }
1128
1129 static const fde *
1130 search_object (struct object* ob, void *pc)
1131 {
1132 /* The fast path initializes objects eagerly to avoid locking.
1133 * On the slow path we initialize them now */
1134 #ifndef ATOMIC_FDE_FAST_PATH
1135 /* If the data hasn't been sorted, try to do this now. We may have
1136 more memory available than last time we tried. */
1137 if (! ob->s.b.sorted)
1138 {
1139 init_object (ob);
1140
1141 /* Despite the above comment, the normal reason to get here is
1142 that we've not processed this object before. A quick range
1143 check is in order. */
1144 if (pc < ob->pc_begin)
1145 return NULL;
1146 }
1147 #endif
1148
1149 if (ob->s.b.sorted)
1150 {
1151 if (ob->s.b.mixed_encoding)
1152 return binary_search_mixed_encoding_fdes (ob, pc);
1153 else if (ob->s.b.encoding == DW_EH_PE_absptr)
1154 return binary_search_unencoded_fdes (ob, pc);
1155 else
1156 return binary_search_single_encoding_fdes (ob, pc);
1157 }
1158 else
1159 {
1160 /* Long slow laborious linear search, cos we've no memory. */
1161 if (ob->s.b.from_array)
1162 {
1163 fde **p;
1164 for (p = ob->u.array; *p ; p++)
1165 {
1166 const fde *f = linear_search_fdes (ob, *p, pc);
1167 if (f)
1168 return f;
1169 }
1170 return NULL;
1171 }
1172 else
1173 return linear_search_fdes (ob, ob->u.single, pc);
1174 }
1175 }
1176
1177 #ifdef ATOMIC_FDE_FAST_PATH
1178
1179 // Check if the object was already initialized
1180 static inline bool
1181 is_object_initialized (struct object *ob)
1182 {
1183 // We have to use acquire atomics for the read, which
1184 // is a bit involved as we read from a bitfield
1185 struct object tmp;
1186 __atomic_load (&(ob->s.b), &(tmp.s.b), __ATOMIC_ACQUIRE);
1187 return tmp.s.b.sorted;
1188 }
1189
1190 #endif
1191
1192 const fde *
1193 _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
1194 {
1195 struct object *ob;
1196 const fde *f = NULL;
1197
1198 #ifdef ATOMIC_FDE_FAST_PATH
1199 ob = btree_lookup (&registered_frames, (uintptr_type) pc);
1200 if (!ob)
1201 return NULL;
1202
1203 // Initialize the object lazily
1204 if (!is_object_initialized (ob))
1205 {
1206 // Check again under mutex
1207 init_object_mutex_once ();
1208 __gthread_mutex_lock (&object_mutex);
1209
1210 if (!ob->s.b.sorted)
1211 {
1212 init_object (ob);
1213 }
1214
1215 __gthread_mutex_unlock (&object_mutex);
1216 }
1217
1218 f = search_object (ob, pc);
1219 #else
1220
1221 init_object_mutex_once ();
1222 __gthread_mutex_lock (&object_mutex);
1223
1224 /* Linear search through the classified objects, to find the one
1225 containing the pc. Note that pc_begin is sorted descending, and
1226 we expect objects to be non-overlapping. */
1227 for (ob = seen_objects; ob; ob = ob->next)
1228 if (pc >= ob->pc_begin)
1229 {
1230 f = search_object (ob, pc);
1231 if (f)
1232 goto fini;
1233 break;
1234 }
1235
1236 /* Classify and search the objects we've not yet processed. */
1237 while ((ob = unseen_objects))
1238 {
1239 struct object **p;
1240
1241 unseen_objects = ob->next;
1242 f = search_object (ob, pc);
1243
1244 /* Insert the object into the classified list. */
1245 for (p = &seen_objects; *p ; p = &(*p)->next)
1246 if ((*p)->pc_begin < ob->pc_begin)
1247 break;
1248 ob->next = *p;
1249 *p = ob;
1250
1251 if (f)
1252 goto fini;
1253 }
1254
1255 fini:
1256 __gthread_mutex_unlock (&object_mutex);
1257 #endif
1258
1259 if (f)
1260 {
1261 int encoding;
1262 _Unwind_Ptr func;
1263
1264 bases->tbase = ob->tbase;
1265 bases->dbase = ob->dbase;
1266
1267 encoding = ob->s.b.encoding;
1268 if (ob->s.b.mixed_encoding)
1269 encoding = get_fde_encoding (f);
1270 read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
1271 f->pc_begin, &func);
1272 bases->func = (void *) func;
1273 }
1274
1275 return f;
1276 }