OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / frame.c
1 /* Subroutines needed for unwinding stack frames for exception handling.  */
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
4    Contributed by Jason Merrill <jason@cygnus.com>.
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* As a special exception, if you link this library with other files,
24    some of which are compiled with GCC, to produce an executable,
25    this library does not by itself cause the resulting executable
26    to be covered by the GNU General Public License.
27    This exception does not however invalidate any other reasons why
28    the executable file might be covered by the GNU General Public License.  */
29
30 /* It is incorrect to include config.h here, because this file is being
31    compiled for the target, and hence definitions concerning only the host
32    do not apply.  */
33
34 #include "tconfig.h"
35
36 /* We disable this when inhibit_libc, so that gcc can still be built without
37    needing header files first.  */
38 /* ??? This is not a good solution, since prototypes may be required in
39    some cases for correct code.  See also libgcc2.c.  */
40 #ifndef inhibit_libc
41 /* fixproto guarantees these system headers exist. */
42 #include <stdlib.h>
43 #include <unistd.h>
44 #endif
45
46 #include "defaults.h"
47
48 #ifdef DWARF2_UNWIND_INFO
49 #include "gansidecl.h"
50 #include "dwarf2.h"
51 #include <stddef.h>
52 #include "frame.h"
53 #include "gthr.h"
54
55 #ifdef __GTHREAD_MUTEX_INIT
56 static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
57 #else
58 static __gthread_mutex_t object_mutex;
59 #endif
60
61 /* Don't use `fancy_abort' here even if config.h says to use it.  */
62 #ifdef abort
63 #undef abort
64 #endif
65
66 /* Some types used by the DWARF 2 spec.  */
67
68 typedef          int  sword __attribute__ ((mode (SI)));
69 typedef unsigned int  uword __attribute__ ((mode (SI)));
70 typedef unsigned int  uaddr __attribute__ ((mode (pointer)));
71 typedef          int  saddr __attribute__ ((mode (pointer)));
72 typedef unsigned char ubyte;
73
74 /* Terminology:
75    CIE - Common Information Element
76    FDE - Frame Descriptor Element
77
78    There is one per function, and it describes where the function code
79    is located, and what the register lifetimes and stack layout are
80    within the function.
81
82    The data structures are defined in the DWARF specfication, although
83    not in a very readable way (see LITERATURE).
84
85    Every time an exception is thrown, the code needs to locate the FDE
86    for the current function, and starts to look for exception regions
87    from that FDE. This works in a two-level search:
88    a) in a linear search, find the shared image (i.e. DLL) containing
89       the PC
90    b) using the FDE table for that shared object, locate the FDE using
91       binary search (which requires the sorting).  */   
92
93 /* The first few fields of a CIE.  The CIE_id field is 0 for a CIE,
94    to distinguish it from a valid FDE.  FDEs are aligned to an addressing
95    unit boundary, but the fields within are unaligned.  */
96
97 struct dwarf_cie {
98   uword length;
99   sword CIE_id;
100   ubyte version;
101   char augmentation[0];
102 } __attribute__ ((packed, aligned (__alignof__ (void *))));
103
104 /* The first few fields of an FDE.  */
105
106 struct dwarf_fde {
107   uword length;
108   sword CIE_delta;
109   void* pc_begin;
110   uaddr pc_range;
111 } __attribute__ ((packed, aligned (__alignof__ (void *))));
112
113 typedef struct dwarf_fde fde;
114
115 /* Objects to be searched for frame unwind info.  */
116
117 static struct object *objects;
118
119 /* The information we care about from a CIE.  */
120
121 struct cie_info {
122   char *augmentation;
123   void *eh_ptr;
124   int code_align;
125   int data_align;
126   unsigned ra_regno;
127 };
128
129 /* The current unwind state, plus a saved copy for DW_CFA_remember_state.  */
130
131 struct frame_state_internal
132 {
133   struct frame_state s;
134   struct frame_state_internal *saved_state;
135 };
136 \f
137 /* This is undefined below if we need it to be an actual function.  */
138 #define init_object_mutex_once()
139
140 #if __GTHREADS
141 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
142
143 /* Helper for init_object_mutex_once.  */
144
145 static void
146 init_object_mutex (void)
147 {
148   __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
149 }
150
151 /* Call this to arrange to initialize the object mutex.  */
152
153 #undef init_object_mutex_once
154 static void
155 init_object_mutex_once (void)
156 {
157   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
158   __gthread_once (&once, init_object_mutex);
159 }
160
161 #endif /* __GTHREAD_MUTEX_INIT_FUNCTION */
162 #endif /* __GTHREADS */
163 \f  
164 /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
165    by R, and return the new value of BUF.  */
166
167 static void *
168 decode_uleb128 (unsigned char *buf, unsigned *r)
169 {
170   unsigned shift = 0;
171   unsigned result = 0;
172
173   while (1)
174     {
175       unsigned byte = *buf++;
176       result |= (byte & 0x7f) << shift;
177       if ((byte & 0x80) == 0)
178         break;
179       shift += 7;
180     }
181   *r = result;
182   return buf;
183 }
184
185 /* Decode the signed LEB128 constant at BUF into the variable pointed to
186    by R, and return the new value of BUF.  */
187
188 static void *
189 decode_sleb128 (unsigned char *buf, int *r)
190 {
191   unsigned shift = 0;
192   unsigned result = 0;
193   unsigned byte;
194
195   while (1)
196     {
197       byte = *buf++;
198       result |= (byte & 0x7f) << shift;
199       shift += 7;
200       if ((byte & 0x80) == 0)
201         break;
202     }
203   if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
204     result |= - (1 << shift);
205
206   *r = result;
207   return buf;
208 }
209
210 /* Read unaligned data from the instruction buffer.  */
211
212 union unaligned {
213   void *p;
214   unsigned b2 __attribute__ ((mode (HI)));
215   unsigned b4 __attribute__ ((mode (SI)));
216   unsigned b8 __attribute__ ((mode (DI)));
217 } __attribute__ ((packed));
218 static inline void *
219 read_pointer (void *p)
220 { union unaligned *up = p; return up->p; }
221 static inline unsigned
222 read_1byte (void *p)
223 { return *(unsigned char *)p; }
224 static inline unsigned
225 read_2byte (void *p)
226 { union unaligned *up = p; return up->b2; }
227 static inline unsigned
228 read_4byte (void *p)
229 { union unaligned *up = p; return up->b4; }
230 static inline unsigned long
231 read_8byte (void *p)
232 { union unaligned *up = p; return up->b8; }
233 \f
234 /* Ordering function for FDEs.  Functions can't overlap, so we just compare
235    their starting addresses.  */
236
237 static inline saddr
238 fde_compare (fde *x, fde *y)
239 {
240   return (saddr)x->pc_begin - (saddr)y->pc_begin;
241 }
242
243 /* Return the address of the FDE after P.  */
244
245 static inline fde *
246 next_fde (fde *p)
247 {
248   return (fde *)(((char *)p) + p->length + sizeof (p->length));
249 }
250
251 /* Sorting an array of FDEs by address.
252    (Ideally we would have the linker sort the FDEs so we don't have to do
253    it at run time. But the linkers are not yet prepared for this.)  */
254
255 /* This is a special mix of insertion sort and heap sort, optimized for
256    the data sets that actually occur. They look like
257    101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130.
258    I.e. a linearly increasing sequence (coming from functions in the text
259    section), with additionally a few unordered elements (coming from functions
260    in gnu_linkonce sections) whose values are higher than the values in the
261    surrounding linear sequence (but not necessarily higher than the values
262    at the end of the linear sequence!).
263    The worst-case total run time is O(N) + O(n log (n)), where N is the
264    total number of FDEs and n is the number of erratic ones.  */
265
266 typedef struct fde_vector
267 {
268   fde **array;
269   size_t count;
270 } fde_vector;
271
272 typedef struct fde_accumulator
273 {
274   fde_vector linear;
275   fde_vector erratic;
276 } fde_accumulator;
277
278 static inline void
279 start_fde_sort (fde_accumulator *accu, size_t count)
280 {
281   accu->linear.array = (fde **) malloc (sizeof (fde *) * count);
282   accu->erratic.array = (fde **) malloc (sizeof (fde *) * count);
283   accu->linear.count = 0;
284   accu->erratic.count = 0;
285 }
286
287 static inline void
288 fde_insert (fde_accumulator *accu, fde *this_fde)
289 {
290   accu->linear.array[accu->linear.count++] = this_fde;
291 }
292
293 /* Split LINEAR into a linear sequence with low values and an erratic
294    sequence with high values, put the linear one (of longest possible
295    length) into LINEAR and the erratic one into ERRATIC. This is O(N).  */
296 static inline void
297 fde_split (fde_vector *linear, fde_vector *erratic)
298 {
299   size_t count = linear->count;
300   size_t linear_max = (size_t) -1;
301   size_t previous_max[count];
302   size_t i, j;
303
304   for (i = 0; i < count; i++)
305     {
306       for (j = linear_max;
307            j != (size_t) -1
308            && fde_compare (linear->array[i], linear->array[j]) < 0;
309            j = previous_max[j])
310         {
311           erratic->array[erratic->count++] = linear->array[j];
312           linear->array[j] = (fde *) NULL;
313         }
314       previous_max[i] = j;
315       linear_max = i;
316     }
317
318   for (i = 0, j = 0; i < count; i++)
319     if (linear->array[i] != (fde *) NULL)
320       linear->array[j++] = linear->array[i];
321   linear->count = j;
322 }
323
324 /* This is O(n log(n)).  BSD/OS defines heapsort in stdlib.h, so we must
325    use a name that does not conflict.  */
326 static inline void
327 frame_heapsort (fde_vector *erratic)
328 {
329   /* For a description of this algorithm, see:
330      Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
331      p. 60-61. */
332   fde ** a = erratic->array;
333   /* A portion of the array is called a "heap" if for all i>=0:
334      If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
335      If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
336 #define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
337   size_t n = erratic->count;
338   size_t m = n;
339   size_t i;
340
341   while (m > 0)
342     {
343       /* Invariant: a[m..n-1] is a heap. */
344       m--;
345       for (i = m; 2*i+1 < n; )
346         {
347           if (2*i+2 < n
348               && fde_compare (a[2*i+2], a[2*i+1]) > 0
349               && fde_compare (a[2*i+2], a[i]) > 0)
350             {
351               SWAP (a[i], a[2*i+2]);
352               i = 2*i+2;
353             }
354           else if (fde_compare (a[2*i+1], a[i]) > 0)
355             {
356               SWAP (a[i], a[2*i+1]);
357               i = 2*i+1;
358             }
359           else
360             break;
361         }
362     }
363   while (n > 1)
364     {
365       /* Invariant: a[0..n-1] is a heap. */
366       n--;
367       SWAP (a[0], a[n]);
368       for (i = 0; 2*i+1 < n; )
369         {
370           if (2*i+2 < n
371               && fde_compare (a[2*i+2], a[2*i+1]) > 0
372               && fde_compare (a[2*i+2], a[i]) > 0)
373             {
374               SWAP (a[i], a[2*i+2]);
375               i = 2*i+2;
376             }
377           else if (fde_compare (a[2*i+1], a[i]) > 0)
378             {
379               SWAP (a[i], a[2*i+1]);
380               i = 2*i+1;
381             }
382           else
383             break;
384         }
385     }
386 #undef SWAP
387 }
388
389 /* Merge V1 and V2, both sorted, and put the result into V1. */
390 static void
391 fde_merge (fde_vector *v1, const fde_vector *v2)
392 {
393   size_t i1, i2;
394   fde * fde2;
395
396   i2 = v2->count;
397   if (i2 > 0)
398     {
399       i1 = v1->count;
400       do {
401         i2--;
402         fde2 = v2->array[i2];
403         while (i1 > 0 && fde_compare (v1->array[i1-1], fde2) > 0)
404           {
405             v1->array[i1+i2] = v1->array[i1-1];
406             i1--;
407           }
408         v1->array[i1+i2] = fde2;
409       } while (i2 > 0);
410       v1->count += v2->count;
411     }
412 }
413
414 static fde **
415 end_fde_sort (fde_accumulator *accu, size_t count)
416 {
417   if (accu->linear.count != count)
418     abort ();
419   fde_split (&accu->linear, &accu->erratic);
420   if (accu->linear.count + accu->erratic.count != count)
421     abort ();
422   frame_heapsort (&accu->erratic);
423   fde_merge (&accu->linear, &accu->erratic);
424   free (accu->erratic.array);
425   return accu->linear.array;
426 }
427
428 static size_t
429 count_fdes (fde *this_fde)
430 {
431   size_t count;
432
433   for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde))
434     {
435       /* Skip CIEs and linked once FDE entries.  */
436       if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0)
437         continue;
438
439       ++count;
440     }
441
442   return count;
443 }
444
445 static void
446 add_fdes (fde *this_fde, fde_accumulator *accu, void **beg_ptr, void **end_ptr)
447 {
448   void *pc_begin = *beg_ptr;
449   void *pc_end = *end_ptr;
450
451   for (; this_fde->length != 0; this_fde = next_fde (this_fde))
452     {
453       /* Skip CIEs and linked once FDE entries.  */
454       if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0)
455         continue;
456
457       fde_insert (accu, this_fde);
458
459       if (this_fde->pc_begin < pc_begin)
460         pc_begin = this_fde->pc_begin;
461       if (this_fde->pc_begin + this_fde->pc_range > pc_end)
462         pc_end = this_fde->pc_begin + this_fde->pc_range;
463     }
464
465   *beg_ptr = pc_begin;
466   *end_ptr = pc_end;
467 }
468
469 /* Set up a sorted array of pointers to FDEs for a loaded object.  We
470    count up the entries before allocating the array because it's likely to
471    be faster.  */
472
473 static void
474 frame_init (struct object* ob)
475 {
476   size_t count;
477   fde_accumulator accu;
478   void *pc_begin, *pc_end;
479
480   if (ob->fde_array)
481     {
482       fde **p = ob->fde_array;
483       for (count = 0; *p; ++p)
484         count += count_fdes (*p);
485     }
486   else
487     count = count_fdes (ob->fde_begin);
488
489   ob->count = count;
490
491   start_fde_sort (&accu, count);
492   pc_begin = (void*)(uaddr)-1;
493   pc_end = 0;
494
495   if (ob->fde_array)
496     {
497       fde **p = ob->fde_array;
498       for (; *p; ++p)
499         add_fdes (*p, &accu, &pc_begin, &pc_end);
500     }
501   else
502     add_fdes (ob->fde_begin, &accu, &pc_begin, &pc_end);
503
504   ob->fde_array = end_fde_sort (&accu, count);
505   ob->pc_begin = pc_begin;
506   ob->pc_end = pc_end;
507 }
508
509 /* Return a pointer to the FDE for the function containing PC.  */
510
511 static fde *
512 find_fde (void *pc)
513 {
514   struct object *ob;
515   size_t lo, hi;
516
517   init_object_mutex_once ();
518   __gthread_mutex_lock (&object_mutex);
519
520   for (ob = objects; ob; ob = ob->next)
521     {
522       if (ob->pc_begin == 0)
523         frame_init (ob);
524       if (pc >= ob->pc_begin && pc < ob->pc_end)
525         break;
526     }
527
528   __gthread_mutex_unlock (&object_mutex);
529
530   if (ob == 0)
531     return 0;
532
533   /* Standard binary search algorithm.  */
534   for (lo = 0, hi = ob->count; lo < hi; )
535     {
536       size_t i = (lo + hi) / 2;
537       fde *f = ob->fde_array[i];
538
539       if (pc < f->pc_begin)
540         hi = i;
541       else if (pc >= f->pc_begin + f->pc_range)
542         lo = i + 1;
543       else
544         return f;
545     }
546
547   return 0;
548 }
549 \f
550 static inline struct dwarf_cie *
551 get_cie (fde *f)
552 {
553   return ((void *)&f->CIE_delta) - f->CIE_delta;
554 }
555
556 /* Extract any interesting information from the CIE for the translation
557    unit F belongs to.  */
558
559 static void *
560 extract_cie_info (fde *f, struct cie_info *c)
561 {
562   void *p;
563   int i;
564
565   c->augmentation = get_cie (f)->augmentation;
566
567   if (strcmp (c->augmentation, "") != 0
568       && strcmp (c->augmentation, "eh") != 0
569       && c->augmentation[0] != 'z')
570     return 0;
571
572   p = c->augmentation + strlen (c->augmentation) + 1;
573
574   if (strcmp (c->augmentation, "eh") == 0)
575     {
576       c->eh_ptr = read_pointer (p);
577       p += sizeof (void *);
578     }
579   else
580     c->eh_ptr = 0;
581
582   p = decode_uleb128 (p, &c->code_align);
583   p = decode_sleb128 (p, &c->data_align);
584   c->ra_regno = *(unsigned char *)p++;
585
586   /* If the augmentation starts with 'z', we now see the length of the
587      augmentation fields.  */
588   if (c->augmentation[0] == 'z')
589     {
590       p = decode_uleb128 (p, &i);
591       p += i;
592     }
593
594   return p;
595 }
596
597 /* Decode one instruction's worth of DWARF 2 call frame information.
598    Used by __frame_state_for.  Takes pointers P to the instruction to
599    decode, STATE to the current register unwind information, INFO to the
600    current CIE information, and PC to the current PC value.  Returns a
601    pointer to the next instruction.  */
602
603 static void *
604 execute_cfa_insn (void *p, struct frame_state_internal *state,
605                   struct cie_info *info, void **pc)
606 {
607   unsigned insn = *(unsigned char *)p++;
608   unsigned reg;
609   int offset;
610
611   if (insn & DW_CFA_advance_loc)
612     *pc += ((insn & 0x3f) * info->code_align);
613   else if (insn & DW_CFA_offset)
614     {
615       reg = (insn & 0x3f);
616       p = decode_uleb128 (p, &offset);
617       offset *= info->data_align;
618       state->s.saved[reg] = REG_SAVED_OFFSET;
619       state->s.reg_or_offset[reg] = offset;
620     }
621   else if (insn & DW_CFA_restore)
622     {
623       reg = (insn & 0x3f);
624       state->s.saved[reg] = REG_UNSAVED;
625     }
626   else switch (insn)
627     {
628     case DW_CFA_set_loc:
629       *pc = read_pointer (p);
630       p += sizeof (void *);
631       break;
632     case DW_CFA_advance_loc1:
633       *pc += read_1byte (p);
634       p += 1;
635       break;
636     case DW_CFA_advance_loc2:
637       *pc += read_2byte (p);
638       p += 2;
639       break;
640     case DW_CFA_advance_loc4:
641       *pc += read_4byte (p);
642       p += 4;
643       break;
644
645     case DW_CFA_offset_extended:
646       p = decode_uleb128 (p, &reg);
647       p = decode_uleb128 (p, &offset);
648       offset *= info->data_align;
649       state->s.saved[reg] = REG_SAVED_OFFSET;
650       state->s.reg_or_offset[reg] = offset;
651       break;
652     case DW_CFA_restore_extended:
653       p = decode_uleb128 (p, &reg);
654       state->s.saved[reg] = REG_UNSAVED;
655       break;
656
657     case DW_CFA_undefined:
658     case DW_CFA_same_value:
659     case DW_CFA_nop:
660       break;
661
662     case DW_CFA_register:
663       {
664         unsigned reg2;
665         p = decode_uleb128 (p, &reg);
666         p = decode_uleb128 (p, &reg2);
667         state->s.saved[reg] = REG_SAVED_REG;
668         state->s.reg_or_offset[reg] = reg2;
669       }
670       break;
671
672     case DW_CFA_def_cfa:
673       p = decode_uleb128 (p, &reg);
674       p = decode_uleb128 (p, &offset);
675       state->s.cfa_reg = reg;
676       state->s.cfa_offset = offset;
677       break;
678     case DW_CFA_def_cfa_register:
679       p = decode_uleb128 (p, &reg);
680       state->s.cfa_reg = reg;
681       break;
682     case DW_CFA_def_cfa_offset:
683       p = decode_uleb128 (p, &offset);
684       state->s.cfa_offset = offset;
685       break;
686       
687     case DW_CFA_remember_state:
688       {
689         struct frame_state_internal *save =
690           (struct frame_state_internal *)
691           malloc (sizeof (struct frame_state_internal));
692         memcpy (save, state, sizeof (struct frame_state_internal));
693         state->saved_state = save;
694       }
695       break;
696     case DW_CFA_restore_state:
697       {
698         struct frame_state_internal *save = state->saved_state;
699         memcpy (state, save, sizeof (struct frame_state_internal));
700         free (save);
701       }
702       break;
703
704       /* FIXME: Hardcoded for SPARC register window configuration.  */
705     case DW_CFA_GNU_window_save:
706       for (reg = 16; reg < 32; ++reg)
707         {
708           state->s.saved[reg] = REG_SAVED_OFFSET;
709           state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *);
710         }
711       break;
712
713     case DW_CFA_GNU_args_size:
714       p = decode_uleb128 (p, &offset);
715       state->s.args_size = offset;
716       break;
717
718     default:
719       abort ();
720     }
721   return p;
722 }
723 \f
724 /* Called from crtbegin.o to register the unwind info for an object.  */
725
726 void
727 __register_frame_info (void *begin, struct object *ob)
728 {
729   ob->fde_begin = begin;
730
731   ob->pc_begin = ob->pc_end = 0;
732   ob->fde_array = 0;
733   ob->count = 0;
734
735   init_object_mutex_once ();
736   __gthread_mutex_lock (&object_mutex);
737
738   ob->next = objects;
739   objects = ob;
740
741   __gthread_mutex_unlock (&object_mutex);
742 }
743
744 void
745 __register_frame (void *begin)
746 {
747   struct object *ob = (struct object *) malloc (sizeof (struct object));
748   __register_frame_info (begin, ob);                       
749 }
750
751 /* Similar, but BEGIN is actually a pointer to a table of unwind entries
752    for different translation units.  Called from the file generated by
753    collect2.  */
754
755 void
756 __register_frame_info_table (void *begin, struct object *ob)
757 {
758   ob->fde_begin = begin;
759   ob->fde_array = begin;
760
761   ob->pc_begin = ob->pc_end = 0;
762   ob->count = 0;
763
764   init_object_mutex_once ();
765   __gthread_mutex_lock (&object_mutex);
766
767   ob->next = objects;
768   objects = ob;
769
770   __gthread_mutex_unlock (&object_mutex);
771 }
772
773 void
774 __register_frame_table (void *begin)
775 {
776   struct object *ob = (struct object *) malloc (sizeof (struct object));
777   __register_frame_info_table (begin, ob);
778 }
779
780 /* Called from crtbegin.o to deregister the unwind info for an object.  */
781
782 void *
783 __deregister_frame_info (void *begin)
784 {
785   struct object **p;
786
787   init_object_mutex_once ();
788   __gthread_mutex_lock (&object_mutex);
789
790   p = &objects;
791   while (*p)
792     {
793       if ((*p)->fde_begin == begin)
794         {
795           struct object *ob = *p;
796           *p = (*p)->next;
797
798           /* If we've run init_frame for this object, free the FDE array.  */
799           if (ob->pc_begin)
800             free (ob->fde_array);
801
802           __gthread_mutex_unlock (&object_mutex);
803           return (void *) ob;
804         }
805       p = &((*p)->next);
806     }
807
808   __gthread_mutex_unlock (&object_mutex);
809   abort ();
810 }
811
812 void
813 __deregister_frame (void *begin)
814 {
815   free (__deregister_frame_info (begin));
816 }
817
818 /* Called from __throw to find the registers to restore for a given
819    PC_TARGET.  The caller should allocate a local variable of `struct
820    frame_state' (declared in frame.h) and pass its address to STATE_IN.  */
821
822 struct frame_state *
823 __frame_state_for (void *pc_target, struct frame_state *state_in)
824 {
825   fde *f;
826   void *insn, *end, *pc;
827   struct cie_info info;
828   struct frame_state_internal state;
829
830   f = find_fde (pc_target);
831   if (f == 0)
832     return 0;
833
834   insn = extract_cie_info (f, &info);
835   if (insn == 0)
836     return 0;
837
838   memset (&state, 0, sizeof (state));
839   state.s.retaddr_column = info.ra_regno;
840   state.s.eh_ptr = info.eh_ptr;
841
842   /* First decode all the insns in the CIE.  */
843   end = next_fde ((fde*) get_cie (f));
844   while (insn < end)
845     insn = execute_cfa_insn (insn, &state, &info, 0);
846
847   insn = ((fde *)f) + 1;
848
849   if (info.augmentation[0] == 'z')
850     {
851       int i;
852       insn = decode_uleb128 (insn, &i);
853       insn += i;
854     }
855
856   /* Then the insns in the FDE up to our target PC.  */
857   end = next_fde (f);
858   pc = f->pc_begin;
859   while (insn < end && pc <= pc_target)
860     insn = execute_cfa_insn (insn, &state, &info, &pc);
861
862   memcpy (state_in, &state.s, sizeof (state.s));
863   return state_in;
864 }
865 #endif /* DWARF2_UNWIND_INFO */