1*38fd1498Szrj /* Subroutines needed for unwinding stack frames for exception handling.  */
2*38fd1498Szrj /* Copyright (C) 1997-2018 Free Software Foundation, Inc.
3*38fd1498Szrj    Contributed by Jason Merrill <jason@cygnus.com>.
4*38fd1498Szrj 
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj 
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj 
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj 
17*38fd1498Szrj Under Section 7 of GPL version 3, you are granted additional
18*38fd1498Szrj permissions described in the GCC Runtime Library Exception, version
19*38fd1498Szrj 3.1, as published by the Free Software Foundation.
20*38fd1498Szrj 
21*38fd1498Szrj You should have received a copy of the GNU General Public License and
22*38fd1498Szrj a copy of the GCC Runtime Library Exception along with this program;
23*38fd1498Szrj see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
25*38fd1498Szrj 
26*38fd1498Szrj #ifndef _Unwind_Find_FDE
27*38fd1498Szrj #include "tconfig.h"
28*38fd1498Szrj #include "tsystem.h"
29*38fd1498Szrj #include "coretypes.h"
30*38fd1498Szrj #include "tm.h"
31*38fd1498Szrj #include "libgcc_tm.h"
32*38fd1498Szrj #include "dwarf2.h"
33*38fd1498Szrj #include "unwind.h"
34*38fd1498Szrj #define NO_BASE_OF_ENCODED_VALUE
35*38fd1498Szrj #include "unwind-pe.h"
36*38fd1498Szrj #include "unwind-dw2-fde.h"
37*38fd1498Szrj #include "gthr.h"
38*38fd1498Szrj #else
39*38fd1498Szrj #if (defined(__GTHREAD_MUTEX_INIT) || defined(__GTHREAD_MUTEX_INIT_FUNCTION)) \
40*38fd1498Szrj     && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
41*38fd1498Szrj #define ATOMIC_FDE_FAST_PATH 1
42*38fd1498Szrj #endif
43*38fd1498Szrj #endif
44*38fd1498Szrj 
45*38fd1498Szrj /* The unseen_objects list contains objects that have been registered
46*38fd1498Szrj    but not yet categorized in any way.  The seen_objects list has had
47*38fd1498Szrj    its pc_begin and count fields initialized at minimum, and is sorted
48*38fd1498Szrj    by decreasing value of pc_begin.  */
49*38fd1498Szrj static struct object *unseen_objects;
50*38fd1498Szrj static struct object *seen_objects;
51*38fd1498Szrj #ifdef ATOMIC_FDE_FAST_PATH
52*38fd1498Szrj static int any_objects_registered;
53*38fd1498Szrj #endif
54*38fd1498Szrj 
55*38fd1498Szrj #ifdef __GTHREAD_MUTEX_INIT
56*38fd1498Szrj static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
57*38fd1498Szrj #define init_object_mutex_once()
58*38fd1498Szrj #else
59*38fd1498Szrj #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
60*38fd1498Szrj static __gthread_mutex_t object_mutex;
61*38fd1498Szrj 
62*38fd1498Szrj static void
init_object_mutex(void)63*38fd1498Szrj init_object_mutex (void)
64*38fd1498Szrj {
65*38fd1498Szrj   __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
66*38fd1498Szrj }
67*38fd1498Szrj 
68*38fd1498Szrj static void
init_object_mutex_once(void)69*38fd1498Szrj init_object_mutex_once (void)
70*38fd1498Szrj {
71*38fd1498Szrj   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
72*38fd1498Szrj   __gthread_once (&once, init_object_mutex);
73*38fd1498Szrj }
74*38fd1498Szrj #else
75*38fd1498Szrj /* ???  Several targets include this file with stubbing parts of gthr.h
76*38fd1498Szrj    and expect no locking to be done.  */
77*38fd1498Szrj #define init_object_mutex_once()
78*38fd1498Szrj static __gthread_mutex_t object_mutex;
79*38fd1498Szrj #endif
80*38fd1498Szrj #endif
81*38fd1498Szrj 
82*38fd1498Szrj /* Called from crtbegin.o to register the unwind info for an object.  */
83*38fd1498Szrj 
84*38fd1498Szrj void
__register_frame_info_bases(const void * begin,struct object * ob,void * tbase,void * dbase)85*38fd1498Szrj __register_frame_info_bases (const void *begin, struct object *ob,
86*38fd1498Szrj 			     void *tbase, void *dbase)
87*38fd1498Szrj {
88*38fd1498Szrj   /* If .eh_frame is empty, don't register at all.  */
89*38fd1498Szrj   if ((const uword *) begin == 0 || *(const uword *) begin == 0)
90*38fd1498Szrj     return;
91*38fd1498Szrj 
92*38fd1498Szrj   ob->pc_begin = (void *)-1;
93*38fd1498Szrj   ob->tbase = tbase;
94*38fd1498Szrj   ob->dbase = dbase;
95*38fd1498Szrj   ob->u.single = begin;
96*38fd1498Szrj   ob->s.i = 0;
97*38fd1498Szrj   ob->s.b.encoding = DW_EH_PE_omit;
98*38fd1498Szrj #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
99*38fd1498Szrj   ob->fde_end = NULL;
100*38fd1498Szrj #endif
101*38fd1498Szrj 
102*38fd1498Szrj   init_object_mutex_once ();
103*38fd1498Szrj   __gthread_mutex_lock (&object_mutex);
104*38fd1498Szrj 
105*38fd1498Szrj   ob->next = unseen_objects;
106*38fd1498Szrj   unseen_objects = ob;
107*38fd1498Szrj #ifdef ATOMIC_FDE_FAST_PATH
108*38fd1498Szrj   /* Set flag that at least one library has registered FDEs.
109*38fd1498Szrj      Use relaxed MO here, it is up to the app to ensure that the library
110*38fd1498Szrj      loading/initialization happens-before using that library in other
111*38fd1498Szrj      threads (in particular unwinding with that library's functions
112*38fd1498Szrj      appearing in the backtraces).  Calling that library's functions
113*38fd1498Szrj      without waiting for the library to initialize would be racy.  */
114*38fd1498Szrj   if (!any_objects_registered)
115*38fd1498Szrj     __atomic_store_n (&any_objects_registered, 1, __ATOMIC_RELAXED);
116*38fd1498Szrj #endif
117*38fd1498Szrj 
118*38fd1498Szrj   __gthread_mutex_unlock (&object_mutex);
119*38fd1498Szrj }
120*38fd1498Szrj 
121*38fd1498Szrj void
__register_frame_info(const void * begin,struct object * ob)122*38fd1498Szrj __register_frame_info (const void *begin, struct object *ob)
123*38fd1498Szrj {
124*38fd1498Szrj   __register_frame_info_bases (begin, ob, 0, 0);
125*38fd1498Szrj }
126*38fd1498Szrj 
127*38fd1498Szrj void
__register_frame(void * begin)128*38fd1498Szrj __register_frame (void *begin)
129*38fd1498Szrj {
130*38fd1498Szrj   struct object *ob;
131*38fd1498Szrj 
132*38fd1498Szrj   /* If .eh_frame is empty, don't register at all.  */
133*38fd1498Szrj   if (*(uword *) begin == 0)
134*38fd1498Szrj     return;
135*38fd1498Szrj 
136*38fd1498Szrj   ob = malloc (sizeof (struct object));
137*38fd1498Szrj   __register_frame_info (begin, ob);
138*38fd1498Szrj }
139*38fd1498Szrj 
140*38fd1498Szrj /* Similar, but BEGIN is actually a pointer to a table of unwind entries
141*38fd1498Szrj    for different translation units.  Called from the file generated by
142*38fd1498Szrj    collect2.  */
143*38fd1498Szrj 
144*38fd1498Szrj void
__register_frame_info_table_bases(void * begin,struct object * ob,void * tbase,void * dbase)145*38fd1498Szrj __register_frame_info_table_bases (void *begin, struct object *ob,
146*38fd1498Szrj 				   void *tbase, void *dbase)
147*38fd1498Szrj {
148*38fd1498Szrj   ob->pc_begin = (void *)-1;
149*38fd1498Szrj   ob->tbase = tbase;
150*38fd1498Szrj   ob->dbase = dbase;
151*38fd1498Szrj   ob->u.array = begin;
152*38fd1498Szrj   ob->s.i = 0;
153*38fd1498Szrj   ob->s.b.from_array = 1;
154*38fd1498Szrj   ob->s.b.encoding = DW_EH_PE_omit;
155*38fd1498Szrj 
156*38fd1498Szrj   init_object_mutex_once ();
157*38fd1498Szrj   __gthread_mutex_lock (&object_mutex);
158*38fd1498Szrj 
159*38fd1498Szrj   ob->next = unseen_objects;
160*38fd1498Szrj   unseen_objects = ob;
161*38fd1498Szrj #ifdef ATOMIC_FDE_FAST_PATH
162*38fd1498Szrj   /* Set flag that at least one library has registered FDEs.
163*38fd1498Szrj      Use relaxed MO here, it is up to the app to ensure that the library
164*38fd1498Szrj      loading/initialization happens-before using that library in other
165*38fd1498Szrj      threads (in particular unwinding with that library's functions
166*38fd1498Szrj      appearing in the backtraces).  Calling that library's functions
167*38fd1498Szrj      without waiting for the library to initialize would be racy.  */
168*38fd1498Szrj   if (!any_objects_registered)
169*38fd1498Szrj     __atomic_store_n (&any_objects_registered, 1, __ATOMIC_RELAXED);
170*38fd1498Szrj #endif
171*38fd1498Szrj 
172*38fd1498Szrj   __gthread_mutex_unlock (&object_mutex);
173*38fd1498Szrj }
174*38fd1498Szrj 
175*38fd1498Szrj void
__register_frame_info_table(void * begin,struct object * ob)176*38fd1498Szrj __register_frame_info_table (void *begin, struct object *ob)
177*38fd1498Szrj {
178*38fd1498Szrj   __register_frame_info_table_bases (begin, ob, 0, 0);
179*38fd1498Szrj }
180*38fd1498Szrj 
181*38fd1498Szrj void
__register_frame_table(void * begin)182*38fd1498Szrj __register_frame_table (void *begin)
183*38fd1498Szrj {
184*38fd1498Szrj   struct object *ob = malloc (sizeof (struct object));
185*38fd1498Szrj   __register_frame_info_table (begin, ob);
186*38fd1498Szrj }
187*38fd1498Szrj 
188*38fd1498Szrj /* Called from crtbegin.o to deregister the unwind info for an object.  */
189*38fd1498Szrj /* ??? Glibc has for a while now exported __register_frame_info and
190*38fd1498Szrj    __deregister_frame_info.  If we call __register_frame_info_bases
191*38fd1498Szrj    from crtbegin (wherein it is declared weak), and this object does
192*38fd1498Szrj    not get pulled from libgcc.a for other reasons, then the
193*38fd1498Szrj    invocation of __deregister_frame_info will be resolved from glibc.
194*38fd1498Szrj    Since the registration did not happen there, we'll die.
195*38fd1498Szrj 
196*38fd1498Szrj    Therefore, declare a new deregistration entry point that does the
197*38fd1498Szrj    exact same thing, but will resolve to the same library as
198*38fd1498Szrj    implements __register_frame_info_bases.  */
199*38fd1498Szrj 
200*38fd1498Szrj void *
__deregister_frame_info_bases(const void * begin)201*38fd1498Szrj __deregister_frame_info_bases (const void *begin)
202*38fd1498Szrj {
203*38fd1498Szrj   struct object **p;
204*38fd1498Szrj   struct object *ob = 0;
205*38fd1498Szrj 
206*38fd1498Szrj   /* If .eh_frame is empty, we haven't registered.  */
207*38fd1498Szrj   if ((const uword *) begin == 0 || *(const uword *) begin == 0)
208*38fd1498Szrj     return ob;
209*38fd1498Szrj 
210*38fd1498Szrj   init_object_mutex_once ();
211*38fd1498Szrj   __gthread_mutex_lock (&object_mutex);
212*38fd1498Szrj 
213*38fd1498Szrj   for (p = &unseen_objects; *p ; p = &(*p)->next)
214*38fd1498Szrj     if ((*p)->u.single == begin)
215*38fd1498Szrj       {
216*38fd1498Szrj 	ob = *p;
217*38fd1498Szrj 	*p = ob->next;
218*38fd1498Szrj 	goto out;
219*38fd1498Szrj       }
220*38fd1498Szrj 
221*38fd1498Szrj   for (p = &seen_objects; *p ; p = &(*p)->next)
222*38fd1498Szrj     if ((*p)->s.b.sorted)
223*38fd1498Szrj       {
224*38fd1498Szrj 	if ((*p)->u.sort->orig_data == begin)
225*38fd1498Szrj 	  {
226*38fd1498Szrj 	    ob = *p;
227*38fd1498Szrj 	    *p = ob->next;
228*38fd1498Szrj 	    free (ob->u.sort);
229*38fd1498Szrj 	    goto out;
230*38fd1498Szrj 	  }
231*38fd1498Szrj       }
232*38fd1498Szrj     else
233*38fd1498Szrj       {
234*38fd1498Szrj 	if ((*p)->u.single == begin)
235*38fd1498Szrj 	  {
236*38fd1498Szrj 	    ob = *p;
237*38fd1498Szrj 	    *p = ob->next;
238*38fd1498Szrj 	    goto out;
239*38fd1498Szrj 	  }
240*38fd1498Szrj       }
241*38fd1498Szrj 
242*38fd1498Szrj  out:
243*38fd1498Szrj   __gthread_mutex_unlock (&object_mutex);
244*38fd1498Szrj   gcc_assert (ob);
245*38fd1498Szrj   return (void *) ob;
246*38fd1498Szrj }
247*38fd1498Szrj 
248*38fd1498Szrj void *
__deregister_frame_info(const void * begin)249*38fd1498Szrj __deregister_frame_info (const void *begin)
250*38fd1498Szrj {
251*38fd1498Szrj   return __deregister_frame_info_bases (begin);
252*38fd1498Szrj }
253*38fd1498Szrj 
254*38fd1498Szrj void
__deregister_frame(void * begin)255*38fd1498Szrj __deregister_frame (void *begin)
256*38fd1498Szrj {
257*38fd1498Szrj   /* If .eh_frame is empty, we haven't registered.  */
258*38fd1498Szrj   if (*(uword *) begin != 0)
259*38fd1498Szrj     free (__deregister_frame_info (begin));
260*38fd1498Szrj }
261*38fd1498Szrj 
262*38fd1498Szrj 
263*38fd1498Szrj /* Like base_of_encoded_value, but take the base from a struct object
264*38fd1498Szrj    instead of an _Unwind_Context.  */
265*38fd1498Szrj 
266*38fd1498Szrj static _Unwind_Ptr
base_from_object(unsigned char encoding,struct object * ob)267*38fd1498Szrj base_from_object (unsigned char encoding, struct object *ob)
268*38fd1498Szrj {
269*38fd1498Szrj   if (encoding == DW_EH_PE_omit)
270*38fd1498Szrj     return 0;
271*38fd1498Szrj 
272*38fd1498Szrj   switch (encoding & 0x70)
273*38fd1498Szrj     {
274*38fd1498Szrj     case DW_EH_PE_absptr:
275*38fd1498Szrj     case DW_EH_PE_pcrel:
276*38fd1498Szrj     case DW_EH_PE_aligned:
277*38fd1498Szrj       return 0;
278*38fd1498Szrj 
279*38fd1498Szrj     case DW_EH_PE_textrel:
280*38fd1498Szrj       return (_Unwind_Ptr) ob->tbase;
281*38fd1498Szrj     case DW_EH_PE_datarel:
282*38fd1498Szrj       return (_Unwind_Ptr) ob->dbase;
283*38fd1498Szrj     default:
284*38fd1498Szrj       gcc_unreachable ();
285*38fd1498Szrj     }
286*38fd1498Szrj }
287*38fd1498Szrj 
288*38fd1498Szrj /* Return the FDE pointer encoding from the CIE.  */
289*38fd1498Szrj /* ??? This is a subset of extract_cie_info from unwind-dw2.c.  */
290*38fd1498Szrj 
291*38fd1498Szrj static int
get_cie_encoding(const struct dwarf_cie * cie)292*38fd1498Szrj get_cie_encoding (const struct dwarf_cie *cie)
293*38fd1498Szrj {
294*38fd1498Szrj   const unsigned char *aug, *p;
295*38fd1498Szrj   _Unwind_Ptr dummy;
296*38fd1498Szrj   _uleb128_t utmp;
297*38fd1498Szrj   _sleb128_t stmp;
298*38fd1498Szrj 
299*38fd1498Szrj   aug = cie->augmentation;
300*38fd1498Szrj   p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string.  */
301*38fd1498Szrj   if (__builtin_expect (cie->version >= 4, 0))
302*38fd1498Szrj     {
303*38fd1498Szrj       if (p[0] != sizeof (void *) || p[1] != 0)
304*38fd1498Szrj 	return DW_EH_PE_omit;		/* We are not prepared to handle unexpected
305*38fd1498Szrj 					   address sizes or segment selectors.  */
306*38fd1498Szrj       p += 2;				/* Skip address size and segment size.  */
307*38fd1498Szrj     }
308*38fd1498Szrj 
309*38fd1498Szrj   if (aug[0] != 'z')
310*38fd1498Szrj     return DW_EH_PE_absptr;
311*38fd1498Szrj 
312*38fd1498Szrj   p = read_uleb128 (p, &utmp);		/* Skip code alignment.  */
313*38fd1498Szrj   p = read_sleb128 (p, &stmp);		/* Skip data alignment.  */
314*38fd1498Szrj   if (cie->version == 1)		/* Skip return address column.  */
315*38fd1498Szrj     p++;
316*38fd1498Szrj   else
317*38fd1498Szrj     p = read_uleb128 (p, &utmp);
318*38fd1498Szrj 
319*38fd1498Szrj   aug++;				/* Skip 'z' */
320*38fd1498Szrj   p = read_uleb128 (p, &utmp);		/* Skip augmentation length.  */
321*38fd1498Szrj   while (1)
322*38fd1498Szrj     {
323*38fd1498Szrj       /* This is what we're looking for.  */
324*38fd1498Szrj       if (*aug == 'R')
325*38fd1498Szrj 	return *p;
326*38fd1498Szrj       /* Personality encoding and pointer.  */
327*38fd1498Szrj       else if (*aug == 'P')
328*38fd1498Szrj 	{
329*38fd1498Szrj 	  /* ??? Avoid dereferencing indirect pointers, since we're
330*38fd1498Szrj 	     faking the base address.  Gotta keep DW_EH_PE_aligned
331*38fd1498Szrj 	     intact, however.  */
332*38fd1498Szrj 	  p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
333*38fd1498Szrj 	}
334*38fd1498Szrj       /* LSDA encoding.  */
335*38fd1498Szrj       else if (*aug == 'L')
336*38fd1498Szrj 	p++;
337*38fd1498Szrj       /* Otherwise end of string, or unknown augmentation.  */
338*38fd1498Szrj       else
339*38fd1498Szrj 	return DW_EH_PE_absptr;
340*38fd1498Szrj       aug++;
341*38fd1498Szrj     }
342*38fd1498Szrj }
343*38fd1498Szrj 
344*38fd1498Szrj static inline int
get_fde_encoding(const struct dwarf_fde * f)345*38fd1498Szrj get_fde_encoding (const struct dwarf_fde *f)
346*38fd1498Szrj {
347*38fd1498Szrj   return get_cie_encoding (get_cie (f));
348*38fd1498Szrj }
349*38fd1498Szrj 
350*38fd1498Szrj 
351*38fd1498Szrj /* Sorting an array of FDEs by address.
352*38fd1498Szrj    (Ideally we would have the linker sort the FDEs so we don't have to do
353*38fd1498Szrj    it at run time. But the linkers are not yet prepared for this.)  */
354*38fd1498Szrj 
355*38fd1498Szrj /* Comparison routines.  Three variants of increasing complexity.  */
356*38fd1498Szrj 
357*38fd1498Szrj static int
fde_unencoded_compare(struct object * ob,const fde * x,const fde * y)358*38fd1498Szrj fde_unencoded_compare (struct object *ob __attribute__((unused)),
359*38fd1498Szrj 		       const fde *x, const fde *y)
360*38fd1498Szrj {
361*38fd1498Szrj   _Unwind_Ptr x_ptr, y_ptr;
362*38fd1498Szrj   memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Ptr));
363*38fd1498Szrj   memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Ptr));
364*38fd1498Szrj 
365*38fd1498Szrj   if (x_ptr > y_ptr)
366*38fd1498Szrj     return 1;
367*38fd1498Szrj   if (x_ptr < y_ptr)
368*38fd1498Szrj     return -1;
369*38fd1498Szrj   return 0;
370*38fd1498Szrj }
371*38fd1498Szrj 
372*38fd1498Szrj static int
fde_single_encoding_compare(struct object * ob,const fde * x,const fde * y)373*38fd1498Szrj fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
374*38fd1498Szrj {
375*38fd1498Szrj   _Unwind_Ptr base, x_ptr, y_ptr;
376*38fd1498Szrj 
377*38fd1498Szrj   base = base_from_object (ob->s.b.encoding, ob);
378*38fd1498Szrj   read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
379*38fd1498Szrj   read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
380*38fd1498Szrj 
381*38fd1498Szrj   if (x_ptr > y_ptr)
382*38fd1498Szrj     return 1;
383*38fd1498Szrj   if (x_ptr < y_ptr)
384*38fd1498Szrj     return -1;
385*38fd1498Szrj   return 0;
386*38fd1498Szrj }
387*38fd1498Szrj 
388*38fd1498Szrj static int
fde_mixed_encoding_compare(struct object * ob,const fde * x,const fde * y)389*38fd1498Szrj fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
390*38fd1498Szrj {
391*38fd1498Szrj   int x_encoding, y_encoding;
392*38fd1498Szrj   _Unwind_Ptr x_ptr, y_ptr;
393*38fd1498Szrj 
394*38fd1498Szrj   x_encoding = get_fde_encoding (x);
395*38fd1498Szrj   read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
396*38fd1498Szrj 				x->pc_begin, &x_ptr);
397*38fd1498Szrj 
398*38fd1498Szrj   y_encoding = get_fde_encoding (y);
399*38fd1498Szrj   read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
400*38fd1498Szrj 				y->pc_begin, &y_ptr);
401*38fd1498Szrj 
402*38fd1498Szrj   if (x_ptr > y_ptr)
403*38fd1498Szrj     return 1;
404*38fd1498Szrj   if (x_ptr < y_ptr)
405*38fd1498Szrj     return -1;
406*38fd1498Szrj   return 0;
407*38fd1498Szrj }
408*38fd1498Szrj 
409*38fd1498Szrj typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
410*38fd1498Szrj 
411*38fd1498Szrj 
412*38fd1498Szrj /* This is a special mix of insertion sort and heap sort, optimized for
413*38fd1498Szrj    the data sets that actually occur. They look like
414*38fd1498Szrj    101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130.
415*38fd1498Szrj    I.e. a linearly increasing sequence (coming from functions in the text
416*38fd1498Szrj    section), with additionally a few unordered elements (coming from functions
417*38fd1498Szrj    in gnu_linkonce sections) whose values are higher than the values in the
418*38fd1498Szrj    surrounding linear sequence (but not necessarily higher than the values
419*38fd1498Szrj    at the end of the linear sequence!).
420*38fd1498Szrj    The worst-case total run time is O(N) + O(n log (n)), where N is the
421*38fd1498Szrj    total number of FDEs and n is the number of erratic ones.  */
422*38fd1498Szrj 
423*38fd1498Szrj struct fde_accumulator
424*38fd1498Szrj {
425*38fd1498Szrj   struct fde_vector *linear;
426*38fd1498Szrj   struct fde_vector *erratic;
427*38fd1498Szrj };
428*38fd1498Szrj 
429*38fd1498Szrj static inline int
start_fde_sort(struct fde_accumulator * accu,size_t count)430*38fd1498Szrj start_fde_sort (struct fde_accumulator *accu, size_t count)
431*38fd1498Szrj {
432*38fd1498Szrj   size_t size;
433*38fd1498Szrj   if (! count)
434*38fd1498Szrj     return 0;
435*38fd1498Szrj 
436*38fd1498Szrj   size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
437*38fd1498Szrj   if ((accu->linear = malloc (size)))
438*38fd1498Szrj     {
439*38fd1498Szrj       accu->linear->count = 0;
440*38fd1498Szrj       if ((accu->erratic = malloc (size)))
441*38fd1498Szrj 	accu->erratic->count = 0;
442*38fd1498Szrj       return 1;
443*38fd1498Szrj     }
444*38fd1498Szrj   else
445*38fd1498Szrj     return 0;
446*38fd1498Szrj }
447*38fd1498Szrj 
448*38fd1498Szrj static inline void
fde_insert(struct fde_accumulator * accu,const fde * this_fde)449*38fd1498Szrj fde_insert (struct fde_accumulator *accu, const fde *this_fde)
450*38fd1498Szrj {
451*38fd1498Szrj   if (accu->linear)
452*38fd1498Szrj     accu->linear->array[accu->linear->count++] = this_fde;
453*38fd1498Szrj }
454*38fd1498Szrj 
455*38fd1498Szrj /* Split LINEAR into a linear sequence with low values and an erratic
456*38fd1498Szrj    sequence with high values, put the linear one (of longest possible
457*38fd1498Szrj    length) into LINEAR and the erratic one into ERRATIC. This is O(N).
458*38fd1498Szrj 
459*38fd1498Szrj    Because the longest linear sequence we are trying to locate within the
460*38fd1498Szrj    incoming LINEAR array can be interspersed with (high valued) erratic
461*38fd1498Szrj    entries.  We construct a chain indicating the sequenced entries.
462*38fd1498Szrj    To avoid having to allocate this chain, we overlay it onto the space of
463*38fd1498Szrj    the ERRATIC array during construction.  A final pass iterates over the
464*38fd1498Szrj    chain to determine what should be placed in the ERRATIC array, and
465*38fd1498Szrj    what is the linear sequence.  This overlay is safe from aliasing.  */
466*38fd1498Szrj 
467*38fd1498Szrj static inline void
fde_split(struct object * ob,fde_compare_t fde_compare,struct fde_vector * linear,struct fde_vector * erratic)468*38fd1498Szrj fde_split (struct object *ob, fde_compare_t fde_compare,
469*38fd1498Szrj 	   struct fde_vector *linear, struct fde_vector *erratic)
470*38fd1498Szrj {
471*38fd1498Szrj   static const fde *marker;
472*38fd1498Szrj   size_t count = linear->count;
473*38fd1498Szrj   const fde *const *chain_end = &marker;
474*38fd1498Szrj   size_t i, j, k;
475*38fd1498Szrj 
476*38fd1498Szrj   /* This should optimize out, but it is wise to make sure this assumption
477*38fd1498Szrj      is correct. Should these have different sizes, we cannot cast between
478*38fd1498Szrj      them and the overlaying onto ERRATIC will not work.  */
479*38fd1498Szrj   gcc_assert (sizeof (const fde *) == sizeof (const fde **));
480*38fd1498Szrj 
481*38fd1498Szrj   for (i = 0; i < count; i++)
482*38fd1498Szrj     {
483*38fd1498Szrj       const fde *const *probe;
484*38fd1498Szrj 
485*38fd1498Szrj       for (probe = chain_end;
486*38fd1498Szrj 	   probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
487*38fd1498Szrj 	   probe = chain_end)
488*38fd1498Szrj 	{
489*38fd1498Szrj 	  chain_end = (const fde *const*) erratic->array[probe - linear->array];
490*38fd1498Szrj 	  erratic->array[probe - linear->array] = NULL;
491*38fd1498Szrj 	}
492*38fd1498Szrj       erratic->array[i] = (const fde *) chain_end;
493*38fd1498Szrj       chain_end = &linear->array[i];
494*38fd1498Szrj     }
495*38fd1498Szrj 
496*38fd1498Szrj   /* Each entry in LINEAR which is part of the linear sequence we have
497*38fd1498Szrj      discovered will correspond to a non-NULL entry in the chain we built in
498*38fd1498Szrj      the ERRATIC array.  */
499*38fd1498Szrj   for (i = j = k = 0; i < count; i++)
500*38fd1498Szrj     if (erratic->array[i])
501*38fd1498Szrj       linear->array[j++] = linear->array[i];
502*38fd1498Szrj     else
503*38fd1498Szrj       erratic->array[k++] = linear->array[i];
504*38fd1498Szrj   linear->count = j;
505*38fd1498Szrj   erratic->count = k;
506*38fd1498Szrj }
507*38fd1498Szrj 
508*38fd1498Szrj #define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
509*38fd1498Szrj 
510*38fd1498Szrj /* Convert a semi-heap to a heap.  A semi-heap is a heap except possibly
511*38fd1498Szrj    for the first (root) node; push it down to its rightful place.  */
512*38fd1498Szrj 
513*38fd1498Szrj static void
frame_downheap(struct object * ob,fde_compare_t fde_compare,const fde ** a,int lo,int hi)514*38fd1498Szrj frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
515*38fd1498Szrj 		int lo, int hi)
516*38fd1498Szrj {
517*38fd1498Szrj   int i, j;
518*38fd1498Szrj 
519*38fd1498Szrj   for (i = lo, j = 2*i+1;
520*38fd1498Szrj        j < hi;
521*38fd1498Szrj        j = 2*i+1)
522*38fd1498Szrj     {
523*38fd1498Szrj       if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
524*38fd1498Szrj 	++j;
525*38fd1498Szrj 
526*38fd1498Szrj       if (fde_compare (ob, a[i], a[j]) < 0)
527*38fd1498Szrj 	{
528*38fd1498Szrj 	  SWAP (a[i], a[j]);
529*38fd1498Szrj 	  i = j;
530*38fd1498Szrj 	}
531*38fd1498Szrj       else
532*38fd1498Szrj 	break;
533*38fd1498Szrj     }
534*38fd1498Szrj }
535*38fd1498Szrj 
536*38fd1498Szrj /* This is O(n log(n)).  BSD/OS defines heapsort in stdlib.h, so we must
537*38fd1498Szrj    use a name that does not conflict.  */
538*38fd1498Szrj 
539*38fd1498Szrj static void
frame_heapsort(struct object * ob,fde_compare_t fde_compare,struct fde_vector * erratic)540*38fd1498Szrj frame_heapsort (struct object *ob, fde_compare_t fde_compare,
541*38fd1498Szrj 		struct fde_vector *erratic)
542*38fd1498Szrj {
543*38fd1498Szrj   /* For a description of this algorithm, see:
544*38fd1498Szrj      Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
545*38fd1498Szrj      p. 60-61.  */
546*38fd1498Szrj   const fde ** a = erratic->array;
547*38fd1498Szrj   /* A portion of the array is called a "heap" if for all i>=0:
548*38fd1498Szrj      If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
549*38fd1498Szrj      If i and 2i+2 are valid indices, then a[i] >= a[2i+2].  */
550*38fd1498Szrj   size_t n = erratic->count;
551*38fd1498Szrj   int m;
552*38fd1498Szrj 
553*38fd1498Szrj   /* Expand our heap incrementally from the end of the array, heapifying
554*38fd1498Szrj      each resulting semi-heap as we go.  After each step, a[m] is the top
555*38fd1498Szrj      of a heap.  */
556*38fd1498Szrj   for (m = n/2-1; m >= 0; --m)
557*38fd1498Szrj     frame_downheap (ob, fde_compare, a, m, n);
558*38fd1498Szrj 
559*38fd1498Szrj   /* Shrink our heap incrementally from the end of the array, first
560*38fd1498Szrj      swapping out the largest element a[0] and then re-heapifying the
561*38fd1498Szrj      resulting semi-heap.  After each step, a[0..m) is a heap.  */
562*38fd1498Szrj   for (m = n-1; m >= 1; --m)
563*38fd1498Szrj     {
564*38fd1498Szrj       SWAP (a[0], a[m]);
565*38fd1498Szrj       frame_downheap (ob, fde_compare, a, 0, m);
566*38fd1498Szrj     }
567*38fd1498Szrj #undef SWAP
568*38fd1498Szrj }
569*38fd1498Szrj 
570*38fd1498Szrj /* Merge V1 and V2, both sorted, and put the result into V1.  */
571*38fd1498Szrj static inline void
fde_merge(struct object * ob,fde_compare_t fde_compare,struct fde_vector * v1,struct fde_vector * v2)572*38fd1498Szrj fde_merge (struct object *ob, fde_compare_t fde_compare,
573*38fd1498Szrj 	   struct fde_vector *v1, struct fde_vector *v2)
574*38fd1498Szrj {
575*38fd1498Szrj   size_t i1, i2;
576*38fd1498Szrj   const fde * fde2;
577*38fd1498Szrj 
578*38fd1498Szrj   i2 = v2->count;
579*38fd1498Szrj   if (i2 > 0)
580*38fd1498Szrj     {
581*38fd1498Szrj       i1 = v1->count;
582*38fd1498Szrj       do
583*38fd1498Szrj 	{
584*38fd1498Szrj 	  i2--;
585*38fd1498Szrj 	  fde2 = v2->array[i2];
586*38fd1498Szrj 	  while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
587*38fd1498Szrj 	    {
588*38fd1498Szrj 	      v1->array[i1+i2] = v1->array[i1-1];
589*38fd1498Szrj 	      i1--;
590*38fd1498Szrj 	    }
591*38fd1498Szrj 	  v1->array[i1+i2] = fde2;
592*38fd1498Szrj 	}
593*38fd1498Szrj       while (i2 > 0);
594*38fd1498Szrj       v1->count += v2->count;
595*38fd1498Szrj     }
596*38fd1498Szrj }
597*38fd1498Szrj 
598*38fd1498Szrj static inline void
end_fde_sort(struct object * ob,struct fde_accumulator * accu,size_t count)599*38fd1498Szrj end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
600*38fd1498Szrj {
601*38fd1498Szrj   fde_compare_t fde_compare;
602*38fd1498Szrj 
603*38fd1498Szrj   gcc_assert (!accu->linear || accu->linear->count == count);
604*38fd1498Szrj 
605*38fd1498Szrj   if (ob->s.b.mixed_encoding)
606*38fd1498Szrj     fde_compare = fde_mixed_encoding_compare;
607*38fd1498Szrj   else if (ob->s.b.encoding == DW_EH_PE_absptr)
608*38fd1498Szrj     fde_compare = fde_unencoded_compare;
609*38fd1498Szrj   else
610*38fd1498Szrj     fde_compare = fde_single_encoding_compare;
611*38fd1498Szrj 
612*38fd1498Szrj   if (accu->erratic)
613*38fd1498Szrj     {
614*38fd1498Szrj       fde_split (ob, fde_compare, accu->linear, accu->erratic);
615*38fd1498Szrj       gcc_assert (accu->linear->count + accu->erratic->count == count);
616*38fd1498Szrj       frame_heapsort (ob, fde_compare, accu->erratic);
617*38fd1498Szrj       fde_merge (ob, fde_compare, accu->linear, accu->erratic);
618*38fd1498Szrj       free (accu->erratic);
619*38fd1498Szrj     }
620*38fd1498Szrj   else
621*38fd1498Szrj     {
622*38fd1498Szrj       /* We've not managed to malloc an erratic array,
623*38fd1498Szrj 	 so heap sort in the linear one.  */
624*38fd1498Szrj       frame_heapsort (ob, fde_compare, accu->linear);
625*38fd1498Szrj     }
626*38fd1498Szrj }
627*38fd1498Szrj 
628*38fd1498Szrj 
629*38fd1498Szrj /* Update encoding, mixed_encoding, and pc_begin for OB for the
630*38fd1498Szrj    fde array beginning at THIS_FDE.  Return the number of fdes
631*38fd1498Szrj    encountered along the way.  */
632*38fd1498Szrj 
633*38fd1498Szrj static size_t
classify_object_over_fdes(struct object * ob,const fde * this_fde)634*38fd1498Szrj classify_object_over_fdes (struct object *ob, const fde *this_fde)
635*38fd1498Szrj {
636*38fd1498Szrj   const struct dwarf_cie *last_cie = 0;
637*38fd1498Szrj   size_t count = 0;
638*38fd1498Szrj   int encoding = DW_EH_PE_absptr;
639*38fd1498Szrj   _Unwind_Ptr base = 0;
640*38fd1498Szrj 
641*38fd1498Szrj   for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
642*38fd1498Szrj     {
643*38fd1498Szrj       const struct dwarf_cie *this_cie;
644*38fd1498Szrj       _Unwind_Ptr mask, pc_begin;
645*38fd1498Szrj 
646*38fd1498Szrj       /* Skip CIEs.  */
647*38fd1498Szrj       if (this_fde->CIE_delta == 0)
648*38fd1498Szrj 	continue;
649*38fd1498Szrj 
650*38fd1498Szrj       /* Determine the encoding for this FDE.  Note mixed encoded
651*38fd1498Szrj 	 objects for later.  */
652*38fd1498Szrj       this_cie = get_cie (this_fde);
653*38fd1498Szrj       if (this_cie != last_cie)
654*38fd1498Szrj 	{
655*38fd1498Szrj 	  last_cie = this_cie;
656*38fd1498Szrj 	  encoding = get_cie_encoding (this_cie);
657*38fd1498Szrj 	  if (encoding == DW_EH_PE_omit)
658*38fd1498Szrj 	    return -1;
659*38fd1498Szrj 	  base = base_from_object (encoding, ob);
660*38fd1498Szrj 	  if (ob->s.b.encoding == DW_EH_PE_omit)
661*38fd1498Szrj 	    ob->s.b.encoding = encoding;
662*38fd1498Szrj 	  else if (ob->s.b.encoding != encoding)
663*38fd1498Szrj 	    ob->s.b.mixed_encoding = 1;
664*38fd1498Szrj 	}
665*38fd1498Szrj 
666*38fd1498Szrj       read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
667*38fd1498Szrj 				    &pc_begin);
668*38fd1498Szrj 
669*38fd1498Szrj       /* Take care to ignore link-once functions that were removed.
670*38fd1498Szrj 	 In these cases, the function address will be NULL, but if
671*38fd1498Szrj 	 the encoding is smaller than a pointer a true NULL may not
672*38fd1498Szrj 	 be representable.  Assume 0 in the representable bits is NULL.  */
673*38fd1498Szrj       mask = size_of_encoded_value (encoding);
674*38fd1498Szrj       if (mask < sizeof (void *))
675*38fd1498Szrj 	mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
676*38fd1498Szrj       else
677*38fd1498Szrj 	mask = -1;
678*38fd1498Szrj 
679*38fd1498Szrj       if ((pc_begin & mask) == 0)
680*38fd1498Szrj 	continue;
681*38fd1498Szrj 
682*38fd1498Szrj       count += 1;
683*38fd1498Szrj       if ((void *) pc_begin < ob->pc_begin)
684*38fd1498Szrj 	ob->pc_begin = (void *) pc_begin;
685*38fd1498Szrj     }
686*38fd1498Szrj 
687*38fd1498Szrj   return count;
688*38fd1498Szrj }
689*38fd1498Szrj 
690*38fd1498Szrj static void
add_fdes(struct object * ob,struct fde_accumulator * accu,const fde * this_fde)691*38fd1498Szrj add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
692*38fd1498Szrj {
693*38fd1498Szrj   const struct dwarf_cie *last_cie = 0;
694*38fd1498Szrj   int encoding = ob->s.b.encoding;
695*38fd1498Szrj   _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
696*38fd1498Szrj 
697*38fd1498Szrj   for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
698*38fd1498Szrj     {
699*38fd1498Szrj       const struct dwarf_cie *this_cie;
700*38fd1498Szrj 
701*38fd1498Szrj       /* Skip CIEs.  */
702*38fd1498Szrj       if (this_fde->CIE_delta == 0)
703*38fd1498Szrj 	continue;
704*38fd1498Szrj 
705*38fd1498Szrj       if (ob->s.b.mixed_encoding)
706*38fd1498Szrj 	{
707*38fd1498Szrj 	  /* Determine the encoding for this FDE.  Note mixed encoded
708*38fd1498Szrj 	     objects for later.  */
709*38fd1498Szrj 	  this_cie = get_cie (this_fde);
710*38fd1498Szrj 	  if (this_cie != last_cie)
711*38fd1498Szrj 	    {
712*38fd1498Szrj 	      last_cie = this_cie;
713*38fd1498Szrj 	      encoding = get_cie_encoding (this_cie);
714*38fd1498Szrj 	      base = base_from_object (encoding, ob);
715*38fd1498Szrj 	    }
716*38fd1498Szrj 	}
717*38fd1498Szrj 
718*38fd1498Szrj       if (encoding == DW_EH_PE_absptr)
719*38fd1498Szrj 	{
720*38fd1498Szrj 	  _Unwind_Ptr ptr;
721*38fd1498Szrj 	  memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Ptr));
722*38fd1498Szrj 	  if (ptr == 0)
723*38fd1498Szrj 	    continue;
724*38fd1498Szrj 	}
725*38fd1498Szrj       else
726*38fd1498Szrj 	{
727*38fd1498Szrj 	  _Unwind_Ptr pc_begin, mask;
728*38fd1498Szrj 
729*38fd1498Szrj 	  read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
730*38fd1498Szrj 					&pc_begin);
731*38fd1498Szrj 
732*38fd1498Szrj 	  /* Take care to ignore link-once functions that were removed.
733*38fd1498Szrj 	     In these cases, the function address will be NULL, but if
734*38fd1498Szrj 	     the encoding is smaller than a pointer a true NULL may not
735*38fd1498Szrj 	     be representable.  Assume 0 in the representable bits is NULL.  */
736*38fd1498Szrj 	  mask = size_of_encoded_value (encoding);
737*38fd1498Szrj 	  if (mask < sizeof (void *))
738*38fd1498Szrj 	    mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
739*38fd1498Szrj 	  else
740*38fd1498Szrj 	    mask = -1;
741*38fd1498Szrj 
742*38fd1498Szrj 	  if ((pc_begin & mask) == 0)
743*38fd1498Szrj 	    continue;
744*38fd1498Szrj 	}
745*38fd1498Szrj 
746*38fd1498Szrj       fde_insert (accu, this_fde);
747*38fd1498Szrj     }
748*38fd1498Szrj }
749*38fd1498Szrj 
750*38fd1498Szrj /* Set up a sorted array of pointers to FDEs for a loaded object.  We
751*38fd1498Szrj    count up the entries before allocating the array because it's likely to
752*38fd1498Szrj    be faster.  We can be called multiple times, should we have failed to
753*38fd1498Szrj    allocate a sorted fde array on a previous occasion.  */
754*38fd1498Szrj 
755*38fd1498Szrj static inline void
init_object(struct object * ob)756*38fd1498Szrj init_object (struct object* ob)
757*38fd1498Szrj {
758*38fd1498Szrj   struct fde_accumulator accu;
759*38fd1498Szrj   size_t count;
760*38fd1498Szrj 
761*38fd1498Szrj   count = ob->s.b.count;
762*38fd1498Szrj   if (count == 0)
763*38fd1498Szrj     {
764*38fd1498Szrj       if (ob->s.b.from_array)
765*38fd1498Szrj 	{
766*38fd1498Szrj 	  fde **p = ob->u.array;
767*38fd1498Szrj 	  for (count = 0; *p; ++p)
768*38fd1498Szrj 	    {
769*38fd1498Szrj 	      size_t cur_count = classify_object_over_fdes (ob, *p);
770*38fd1498Szrj 	      if (cur_count == (size_t) -1)
771*38fd1498Szrj 		goto unhandled_fdes;
772*38fd1498Szrj 	      count += cur_count;
773*38fd1498Szrj 	    }
774*38fd1498Szrj 	}
775*38fd1498Szrj       else
776*38fd1498Szrj 	{
777*38fd1498Szrj 	  count = classify_object_over_fdes (ob, ob->u.single);
778*38fd1498Szrj 	  if (count == (size_t) -1)
779*38fd1498Szrj 	    {
780*38fd1498Szrj 	      static const fde terminator;
781*38fd1498Szrj 	    unhandled_fdes:
782*38fd1498Szrj 	      ob->s.i = 0;
783*38fd1498Szrj 	      ob->s.b.encoding = DW_EH_PE_omit;
784*38fd1498Szrj 	      ob->u.single = &terminator;
785*38fd1498Szrj 	      return;
786*38fd1498Szrj 	    }
787*38fd1498Szrj 	}
788*38fd1498Szrj 
789*38fd1498Szrj       /* The count field we have in the main struct object is somewhat
790*38fd1498Szrj 	 limited, but should suffice for virtually all cases.  If the
791*38fd1498Szrj 	 counted value doesn't fit, re-write a zero.  The worst that
792*38fd1498Szrj 	 happens is that we re-count next time -- admittedly non-trivial
793*38fd1498Szrj 	 in that this implies some 2M fdes, but at least we function.  */
794*38fd1498Szrj       ob->s.b.count = count;
795*38fd1498Szrj       if (ob->s.b.count != count)
796*38fd1498Szrj 	ob->s.b.count = 0;
797*38fd1498Szrj     }
798*38fd1498Szrj 
799*38fd1498Szrj   if (!start_fde_sort (&accu, count))
800*38fd1498Szrj     return;
801*38fd1498Szrj 
802*38fd1498Szrj   if (ob->s.b.from_array)
803*38fd1498Szrj     {
804*38fd1498Szrj       fde **p;
805*38fd1498Szrj       for (p = ob->u.array; *p; ++p)
806*38fd1498Szrj 	add_fdes (ob, &accu, *p);
807*38fd1498Szrj     }
808*38fd1498Szrj   else
809*38fd1498Szrj     add_fdes (ob, &accu, ob->u.single);
810*38fd1498Szrj 
811*38fd1498Szrj   end_fde_sort (ob, &accu, count);
812*38fd1498Szrj 
813*38fd1498Szrj   /* Save the original fde pointer, since this is the key by which the
814*38fd1498Szrj      DSO will deregister the object.  */
815*38fd1498Szrj   accu.linear->orig_data = ob->u.single;
816*38fd1498Szrj   ob->u.sort = accu.linear;
817*38fd1498Szrj 
818*38fd1498Szrj   ob->s.b.sorted = 1;
819*38fd1498Szrj }
820*38fd1498Szrj 
821*38fd1498Szrj /* A linear search through a set of FDEs for the given PC.  This is
822*38fd1498Szrj    used when there was insufficient memory to allocate and sort an
823*38fd1498Szrj    array.  */
824*38fd1498Szrj 
825*38fd1498Szrj static const fde *
linear_search_fdes(struct object * ob,const fde * this_fde,void * pc)826*38fd1498Szrj linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
827*38fd1498Szrj {
828*38fd1498Szrj   const struct dwarf_cie *last_cie = 0;
829*38fd1498Szrj   int encoding = ob->s.b.encoding;
830*38fd1498Szrj   _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
831*38fd1498Szrj 
832*38fd1498Szrj   for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
833*38fd1498Szrj     {
834*38fd1498Szrj       const struct dwarf_cie *this_cie;
835*38fd1498Szrj       _Unwind_Ptr pc_begin, pc_range;
836*38fd1498Szrj 
837*38fd1498Szrj       /* Skip CIEs.  */
838*38fd1498Szrj       if (this_fde->CIE_delta == 0)
839*38fd1498Szrj 	continue;
840*38fd1498Szrj 
841*38fd1498Szrj       if (ob->s.b.mixed_encoding)
842*38fd1498Szrj 	{
843*38fd1498Szrj 	  /* Determine the encoding for this FDE.  Note mixed encoded
844*38fd1498Szrj 	     objects for later.  */
845*38fd1498Szrj 	  this_cie = get_cie (this_fde);
846*38fd1498Szrj 	  if (this_cie != last_cie)
847*38fd1498Szrj 	    {
848*38fd1498Szrj 	      last_cie = this_cie;
849*38fd1498Szrj 	      encoding = get_cie_encoding (this_cie);
850*38fd1498Szrj 	      base = base_from_object (encoding, ob);
851*38fd1498Szrj 	    }
852*38fd1498Szrj 	}
853*38fd1498Szrj 
854*38fd1498Szrj       if (encoding == DW_EH_PE_absptr)
855*38fd1498Szrj 	{
856*38fd1498Szrj 	  const _Unwind_Ptr *pc_array = (const _Unwind_Ptr *) this_fde->pc_begin;
857*38fd1498Szrj 	  pc_begin = pc_array[0];
858*38fd1498Szrj 	  pc_range = pc_array[1];
859*38fd1498Szrj 	  if (pc_begin == 0)
860*38fd1498Szrj 	    continue;
861*38fd1498Szrj 	}
862*38fd1498Szrj       else
863*38fd1498Szrj 	{
864*38fd1498Szrj 	  _Unwind_Ptr mask;
865*38fd1498Szrj 	  const unsigned char *p;
866*38fd1498Szrj 
867*38fd1498Szrj 	  p = read_encoded_value_with_base (encoding, base,
868*38fd1498Szrj 					    this_fde->pc_begin, &pc_begin);
869*38fd1498Szrj 	  read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
870*38fd1498Szrj 
871*38fd1498Szrj 	  /* Take care to ignore link-once functions that were removed.
872*38fd1498Szrj 	     In these cases, the function address will be NULL, but if
873*38fd1498Szrj 	     the encoding is smaller than a pointer a true NULL may not
874*38fd1498Szrj 	     be representable.  Assume 0 in the representable bits is NULL.  */
875*38fd1498Szrj 	  mask = size_of_encoded_value (encoding);
876*38fd1498Szrj 	  if (mask < sizeof (void *))
877*38fd1498Szrj 	    mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1;
878*38fd1498Szrj 	  else
879*38fd1498Szrj 	    mask = -1;
880*38fd1498Szrj 
881*38fd1498Szrj 	  if ((pc_begin & mask) == 0)
882*38fd1498Szrj 	    continue;
883*38fd1498Szrj 	}
884*38fd1498Szrj 
885*38fd1498Szrj       if ((_Unwind_Ptr) pc - pc_begin < pc_range)
886*38fd1498Szrj 	return this_fde;
887*38fd1498Szrj     }
888*38fd1498Szrj 
889*38fd1498Szrj   return NULL;
890*38fd1498Szrj }
891*38fd1498Szrj 
892*38fd1498Szrj /* Binary search for an FDE containing the given PC.  Here are three
893*38fd1498Szrj    implementations of increasing complexity.  */
894*38fd1498Szrj 
895*38fd1498Szrj static inline const fde *
binary_search_unencoded_fdes(struct object * ob,void * pc)896*38fd1498Szrj binary_search_unencoded_fdes (struct object *ob, void *pc)
897*38fd1498Szrj {
898*38fd1498Szrj   struct fde_vector *vec = ob->u.sort;
899*38fd1498Szrj   size_t lo, hi;
900*38fd1498Szrj 
901*38fd1498Szrj   for (lo = 0, hi = vec->count; lo < hi; )
902*38fd1498Szrj     {
903*38fd1498Szrj       size_t i = (lo + hi) / 2;
904*38fd1498Szrj       const fde *const f = vec->array[i];
905*38fd1498Szrj       void *pc_begin;
906*38fd1498Szrj       uaddr pc_range;
907*38fd1498Szrj       memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *));
908*38fd1498Szrj       memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
909*38fd1498Szrj 
910*38fd1498Szrj       if (pc < pc_begin)
911*38fd1498Szrj 	hi = i;
912*38fd1498Szrj       else if (pc >= pc_begin + pc_range)
913*38fd1498Szrj 	lo = i + 1;
914*38fd1498Szrj       else
915*38fd1498Szrj 	return f;
916*38fd1498Szrj     }
917*38fd1498Szrj 
918*38fd1498Szrj   return NULL;
919*38fd1498Szrj }
920*38fd1498Szrj 
921*38fd1498Szrj static inline const fde *
binary_search_single_encoding_fdes(struct object * ob,void * pc)922*38fd1498Szrj binary_search_single_encoding_fdes (struct object *ob, void *pc)
923*38fd1498Szrj {
924*38fd1498Szrj   struct fde_vector *vec = ob->u.sort;
925*38fd1498Szrj   int encoding = ob->s.b.encoding;
926*38fd1498Szrj   _Unwind_Ptr base = base_from_object (encoding, ob);
927*38fd1498Szrj   size_t lo, hi;
928*38fd1498Szrj 
929*38fd1498Szrj   for (lo = 0, hi = vec->count; lo < hi; )
930*38fd1498Szrj     {
931*38fd1498Szrj       size_t i = (lo + hi) / 2;
932*38fd1498Szrj       const fde *f = vec->array[i];
933*38fd1498Szrj       _Unwind_Ptr pc_begin, pc_range;
934*38fd1498Szrj       const unsigned char *p;
935*38fd1498Szrj 
936*38fd1498Szrj       p = read_encoded_value_with_base (encoding, base, f->pc_begin,
937*38fd1498Szrj 					&pc_begin);
938*38fd1498Szrj       read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
939*38fd1498Szrj 
940*38fd1498Szrj       if ((_Unwind_Ptr) pc < pc_begin)
941*38fd1498Szrj 	hi = i;
942*38fd1498Szrj       else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
943*38fd1498Szrj 	lo = i + 1;
944*38fd1498Szrj       else
945*38fd1498Szrj 	return f;
946*38fd1498Szrj     }
947*38fd1498Szrj 
948*38fd1498Szrj   return NULL;
949*38fd1498Szrj }
950*38fd1498Szrj 
951*38fd1498Szrj static inline const fde *
binary_search_mixed_encoding_fdes(struct object * ob,void * pc)952*38fd1498Szrj binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
953*38fd1498Szrj {
954*38fd1498Szrj   struct fde_vector *vec = ob->u.sort;
955*38fd1498Szrj   size_t lo, hi;
956*38fd1498Szrj 
957*38fd1498Szrj   for (lo = 0, hi = vec->count; lo < hi; )
958*38fd1498Szrj     {
959*38fd1498Szrj       size_t i = (lo + hi) / 2;
960*38fd1498Szrj       const fde *f = vec->array[i];
961*38fd1498Szrj       _Unwind_Ptr pc_begin, pc_range;
962*38fd1498Szrj       const unsigned char *p;
963*38fd1498Szrj       int encoding;
964*38fd1498Szrj 
965*38fd1498Szrj       encoding = get_fde_encoding (f);
966*38fd1498Szrj       p = read_encoded_value_with_base (encoding,
967*38fd1498Szrj 					base_from_object (encoding, ob),
968*38fd1498Szrj 					f->pc_begin, &pc_begin);
969*38fd1498Szrj       read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
970*38fd1498Szrj 
971*38fd1498Szrj       if ((_Unwind_Ptr) pc < pc_begin)
972*38fd1498Szrj 	hi = i;
973*38fd1498Szrj       else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
974*38fd1498Szrj 	lo = i + 1;
975*38fd1498Szrj       else
976*38fd1498Szrj 	return f;
977*38fd1498Szrj     }
978*38fd1498Szrj 
979*38fd1498Szrj   return NULL;
980*38fd1498Szrj }
981*38fd1498Szrj 
982*38fd1498Szrj static const fde *
search_object(struct object * ob,void * pc)983*38fd1498Szrj search_object (struct object* ob, void *pc)
984*38fd1498Szrj {
985*38fd1498Szrj   /* If the data hasn't been sorted, try to do this now.  We may have
986*38fd1498Szrj      more memory available than last time we tried.  */
987*38fd1498Szrj   if (! ob->s.b.sorted)
988*38fd1498Szrj     {
989*38fd1498Szrj       init_object (ob);
990*38fd1498Szrj 
991*38fd1498Szrj       /* Despite the above comment, the normal reason to get here is
992*38fd1498Szrj 	 that we've not processed this object before.  A quick range
993*38fd1498Szrj 	 check is in order.  */
994*38fd1498Szrj       if (pc < ob->pc_begin)
995*38fd1498Szrj 	return NULL;
996*38fd1498Szrj     }
997*38fd1498Szrj 
998*38fd1498Szrj   if (ob->s.b.sorted)
999*38fd1498Szrj     {
1000*38fd1498Szrj       if (ob->s.b.mixed_encoding)
1001*38fd1498Szrj 	return binary_search_mixed_encoding_fdes (ob, pc);
1002*38fd1498Szrj       else if (ob->s.b.encoding == DW_EH_PE_absptr)
1003*38fd1498Szrj 	return binary_search_unencoded_fdes (ob, pc);
1004*38fd1498Szrj       else
1005*38fd1498Szrj 	return binary_search_single_encoding_fdes (ob, pc);
1006*38fd1498Szrj     }
1007*38fd1498Szrj   else
1008*38fd1498Szrj     {
1009*38fd1498Szrj       /* Long slow laborious linear search, cos we've no memory.  */
1010*38fd1498Szrj       if (ob->s.b.from_array)
1011*38fd1498Szrj 	{
1012*38fd1498Szrj 	  fde **p;
1013*38fd1498Szrj 	  for (p = ob->u.array; *p ; p++)
1014*38fd1498Szrj 	    {
1015*38fd1498Szrj 	      const fde *f = linear_search_fdes (ob, *p, pc);
1016*38fd1498Szrj 	      if (f)
1017*38fd1498Szrj 		return f;
1018*38fd1498Szrj 	    }
1019*38fd1498Szrj 	  return NULL;
1020*38fd1498Szrj 	}
1021*38fd1498Szrj       else
1022*38fd1498Szrj 	return linear_search_fdes (ob, ob->u.single, pc);
1023*38fd1498Szrj     }
1024*38fd1498Szrj }
1025*38fd1498Szrj 
1026*38fd1498Szrj const fde *
_Unwind_Find_FDE(void * pc,struct dwarf_eh_bases * bases)1027*38fd1498Szrj _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
1028*38fd1498Szrj {
1029*38fd1498Szrj   struct object *ob;
1030*38fd1498Szrj   const fde *f = NULL;
1031*38fd1498Szrj 
1032*38fd1498Szrj #ifdef ATOMIC_FDE_FAST_PATH
1033*38fd1498Szrj   /* For targets where unwind info is usually not registered through these
1034*38fd1498Szrj      APIs anymore, avoid taking a global lock.
1035*38fd1498Szrj      Use relaxed MO here, it is up to the app to ensure that the library
1036*38fd1498Szrj      loading/initialization happens-before using that library in other
1037*38fd1498Szrj      threads (in particular unwinding with that library's functions
1038*38fd1498Szrj      appearing in the backtraces).  Calling that library's functions
1039*38fd1498Szrj      without waiting for the library to initialize would be racy.  */
1040*38fd1498Szrj   if (__builtin_expect (!__atomic_load_n (&any_objects_registered,
1041*38fd1498Szrj 					  __ATOMIC_RELAXED), 1))
1042*38fd1498Szrj     return NULL;
1043*38fd1498Szrj #endif
1044*38fd1498Szrj 
1045*38fd1498Szrj   init_object_mutex_once ();
1046*38fd1498Szrj   __gthread_mutex_lock (&object_mutex);
1047*38fd1498Szrj 
1048*38fd1498Szrj   /* Linear search through the classified objects, to find the one
1049*38fd1498Szrj      containing the pc.  Note that pc_begin is sorted descending, and
1050*38fd1498Szrj      we expect objects to be non-overlapping.  */
1051*38fd1498Szrj   for (ob = seen_objects; ob; ob = ob->next)
1052*38fd1498Szrj     if (pc >= ob->pc_begin)
1053*38fd1498Szrj       {
1054*38fd1498Szrj 	f = search_object (ob, pc);
1055*38fd1498Szrj 	if (f)
1056*38fd1498Szrj 	  goto fini;
1057*38fd1498Szrj 	break;
1058*38fd1498Szrj       }
1059*38fd1498Szrj 
1060*38fd1498Szrj   /* Classify and search the objects we've not yet processed.  */
1061*38fd1498Szrj   while ((ob = unseen_objects))
1062*38fd1498Szrj     {
1063*38fd1498Szrj       struct object **p;
1064*38fd1498Szrj 
1065*38fd1498Szrj       unseen_objects = ob->next;
1066*38fd1498Szrj       f = search_object (ob, pc);
1067*38fd1498Szrj 
1068*38fd1498Szrj       /* Insert the object into the classified list.  */
1069*38fd1498Szrj       for (p = &seen_objects; *p ; p = &(*p)->next)
1070*38fd1498Szrj 	if ((*p)->pc_begin < ob->pc_begin)
1071*38fd1498Szrj 	  break;
1072*38fd1498Szrj       ob->next = *p;
1073*38fd1498Szrj       *p = ob;
1074*38fd1498Szrj 
1075*38fd1498Szrj       if (f)
1076*38fd1498Szrj 	goto fini;
1077*38fd1498Szrj     }
1078*38fd1498Szrj 
1079*38fd1498Szrj  fini:
1080*38fd1498Szrj   __gthread_mutex_unlock (&object_mutex);
1081*38fd1498Szrj 
1082*38fd1498Szrj   if (f)
1083*38fd1498Szrj     {
1084*38fd1498Szrj       int encoding;
1085*38fd1498Szrj       _Unwind_Ptr func;
1086*38fd1498Szrj 
1087*38fd1498Szrj       bases->tbase = ob->tbase;
1088*38fd1498Szrj       bases->dbase = ob->dbase;
1089*38fd1498Szrj 
1090*38fd1498Szrj       encoding = ob->s.b.encoding;
1091*38fd1498Szrj       if (ob->s.b.mixed_encoding)
1092*38fd1498Szrj 	encoding = get_fde_encoding (f);
1093*38fd1498Szrj       read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
1094*38fd1498Szrj 				    f->pc_begin, &func);
1095*38fd1498Szrj       bases->func = (void *) func;
1096*38fd1498Szrj     }
1097*38fd1498Szrj 
1098*38fd1498Szrj   return f;
1099*38fd1498Szrj }
1100