OSDN Git Service

* frame.c (find_fde): Correct FDE's upper bound.
[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 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 #include "defaults.h"
36
37 #ifdef DWARF2_UNWIND_INFO
38 #include "gansidecl.h"
39 #include "dwarf2.h"
40 #include <stddef.h>
41 #include "frame.h"
42 #include "gthr.h"
43
44 #ifdef __GTHREAD_MUTEX_INIT
45 static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
46 #else
47 static __gthread_mutex_t object_mutex;
48 #endif
49
50 /* Don't use `fancy_abort' here even if config.h says to use it.  */
51 #ifdef abort
52 #undef abort
53 #endif
54
55 /* Some types used by the DWARF 2 spec.  */
56
57 typedef          int  sword __attribute__ ((mode (SI)));
58 typedef unsigned int  uword __attribute__ ((mode (SI)));
59 typedef unsigned int  uaddr __attribute__ ((mode (pointer)));
60 typedef          int  saddr __attribute__ ((mode (pointer)));
61 typedef unsigned char ubyte;
62
63 /* The first few fields of a CIE.  The CIE_id field is 0xffffffff for a CIE,
64    to distinguish it from a valid FDE.  FDEs are aligned to an addressing
65    unit boundary, but the fields within are unaligned.  */
66
67 struct dwarf_cie {
68   uword length;
69   sword CIE_id;
70   ubyte version;
71   char augmentation[0];
72 } __attribute__ ((packed, aligned (__alignof__ (void *))));
73
74 /* The first few fields of an FDE.  */
75
76 struct dwarf_fde {
77   uword length;
78   sword CIE_delta;
79   void* pc_begin;
80   uaddr pc_range;
81 } __attribute__ ((packed, aligned (__alignof__ (void *))));
82
83 typedef struct dwarf_fde fde;
84
85 /* Objects to be searched for frame unwind info.  */
86
87 static struct object *objects;
88
89 /* The information we care about from a CIE.  */
90
91 struct cie_info {
92   char *augmentation;
93   void *eh_ptr;
94   int code_align;
95   int data_align;
96   unsigned ra_regno;
97 };
98
99 /* The current unwind state, plus a saved copy for DW_CFA_remember_state.  */
100
101 struct frame_state_internal
102 {
103   struct frame_state s;
104   struct frame_state_internal *saved_state;
105 };
106 \f  
107 /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
108    by R, and return the new value of BUF.  */
109
110 static void *
111 decode_uleb128 (unsigned char *buf, unsigned *r)
112 {
113   unsigned shift = 0;
114   unsigned result = 0;
115
116   while (1)
117     {
118       unsigned byte = *buf++;
119       result |= (byte & 0x7f) << shift;
120       if ((byte & 0x80) == 0)
121         break;
122       shift += 7;
123     }
124   *r = result;
125   return buf;
126 }
127
128 /* Decode the signed LEB128 constant at BUF into the variable pointed to
129    by R, and return the new value of BUF.  */
130
131 static void *
132 decode_sleb128 (unsigned char *buf, int *r)
133 {
134   unsigned shift = 0;
135   unsigned result = 0;
136   unsigned byte;
137
138   while (1)
139     {
140       byte = *buf++;
141       result |= (byte & 0x7f) << shift;
142       shift += 7;
143       if ((byte & 0x80) == 0)
144         break;
145     }
146   if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
147     result |= - (1 << shift);
148
149   *r = result;
150   return buf;
151 }
152
153 /* Read unaligned data from the instruction buffer.  */
154
155 union unaligned {
156   void *p;
157   unsigned b2 __attribute__ ((mode (HI)));
158   unsigned b4 __attribute__ ((mode (SI)));
159   unsigned b8 __attribute__ ((mode (DI)));
160 } __attribute__ ((packed));
161 static inline void *
162 read_pointer (void *p)
163 { union unaligned *up = p; return up->p; }
164 static inline unsigned
165 read_1byte (void *p)
166 { return *(unsigned char *)p; }
167 static inline unsigned
168 read_2byte (void *p)
169 { union unaligned *up = p; return up->b2; }
170 static inline unsigned
171 read_4byte (void *p)
172 { union unaligned *up = p; return up->b4; }
173 static inline unsigned long
174 read_8byte (void *p)
175 { union unaligned *up = p; return up->b8; }
176 \f
177 /* Ordering function for FDEs.  Functions can't overlap, so we just compare
178    their starting addresses.  */
179
180 static inline saddr
181 fde_compare (fde *x, fde *y)
182 {
183   return (saddr)x->pc_begin - (saddr)y->pc_begin;
184 }
185
186 /* Return the address of the FDE after P.  */
187
188 static inline fde *
189 next_fde (fde *p)
190 {
191   return (fde *)(((char *)p) + p->length + sizeof (p->length));
192 }
193
194 /* One iteration of an insertion sort, for adding new FDEs to the array.
195    Usually the new FDE will go in at the end, so we can expect close to
196    O(n) performance.  If this turns out to be overly optimistic, we can have
197    the linker sort the FDEs so we don't have to do it at run time.  */
198
199 static void
200 fde_insert (fde **array, size_t i, fde *this_fde)
201 {
202   array[i] = this_fde;
203
204   for (; i > 0 && fde_compare (array[i], array[i-1]) < 0; --i)
205     {
206       this_fde = array[i];
207       array[i] = array[i-1];
208       array[i-1] = this_fde;
209     }
210 }
211
212 static size_t
213 count_fdes (fde *this_fde)
214 {
215   size_t count;
216
217   for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde))
218     {
219       /* Skip CIEs and linked once FDE entries.  */
220       if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0)
221         continue;
222
223       ++count;
224     }
225
226   return count;
227 }
228
229 static void
230 add_fdes (fde *this_fde, fde **array, size_t *i_ptr,
231           void **beg_ptr, void **end_ptr)
232 {
233   size_t i = *i_ptr;
234   void *pc_begin = *beg_ptr;
235   void *pc_end = *end_ptr;
236
237   for (; this_fde->length != 0; this_fde = next_fde (this_fde))
238     {
239       /* Skip CIEs and linked once FDE entries.  */
240       if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0)
241         continue;
242
243       fde_insert (array, i++, this_fde);
244
245       if (this_fde->pc_begin < pc_begin)
246         pc_begin = this_fde->pc_begin;
247       if (this_fde->pc_begin + this_fde->pc_range > pc_end)
248         pc_end = this_fde->pc_begin + this_fde->pc_range;
249     }
250
251   *i_ptr = i;
252   *beg_ptr = pc_begin;
253   *end_ptr = pc_end;
254 }
255
256 /* Set up a sorted array of pointers to FDEs for a loaded object.  We
257    count up the entries before allocating the array because it's likely to
258    be faster.  */
259
260 static void
261 frame_init (struct object* ob)
262 {
263   fde *this_fde;
264   size_t count;
265   fde **array;
266   void *pc_begin, *pc_end;
267
268   if (ob->fde_array)
269     {
270       fde **p = ob->fde_array;
271       for (count = 0; *p; ++p)
272         count += count_fdes (*p);
273     }
274   else
275     count = count_fdes (ob->fde_begin);
276
277   ob->count = count;
278   array = (fde **) malloc (sizeof (fde *) * count);
279
280   pc_begin = (void*)(uaddr)-1;
281   pc_end = 0;
282   count = 0;
283
284   if (ob->fde_array)
285     {
286       fde **p = ob->fde_array;
287       for (; *p; ++p)
288         add_fdes (*p, array, &count, &pc_begin, &pc_end);
289     }
290   else
291     add_fdes (ob->fde_begin, array, &count, &pc_begin, &pc_end);
292
293   ob->fde_array = array;
294   ob->pc_begin = pc_begin;
295   ob->pc_end = pc_end;
296 }
297
298 /* Return a pointer to the FDE for the function containing PC.  */
299
300 static fde *
301 find_fde (void *pc)
302 {
303   struct object *ob;
304   size_t lo, hi;
305
306   __gthread_mutex_lock (&object_mutex);
307
308   for (ob = objects; ob; ob = ob->next)
309     {
310       if (ob->pc_begin == 0)
311         frame_init (ob);
312       if (pc >= ob->pc_begin && pc < ob->pc_end)
313         break;
314     }
315
316   __gthread_mutex_unlock (&object_mutex);
317
318   if (ob == 0)
319     return 0;
320
321   /* Standard binary search algorithm.  */
322   for (lo = 0, hi = ob->count; lo < hi; )
323     {
324       size_t i = (lo + hi) / 2;
325       fde *f = ob->fde_array[i];
326
327       if (pc < f->pc_begin)
328         hi = i;
329       else if (pc >= f->pc_begin + f->pc_range)
330         lo = i + 1;
331       else
332         return f;
333     }
334
335   return 0;
336 }
337 \f
338 static inline struct dwarf_cie *
339 get_cie (fde *f)
340 {
341   return ((void *)&f->CIE_delta) - f->CIE_delta;
342 }
343
344 /* Extract any interesting information from the CIE for the translation
345    unit F belongs to.  */
346
347 static void *
348 extract_cie_info (fde *f, struct cie_info *c)
349 {
350   void *p;
351   int i;
352
353   c->augmentation = get_cie (f)->augmentation;
354
355   if (strcmp (c->augmentation, "") != 0
356       && strcmp (c->augmentation, "eh") != 0
357       && c->augmentation[0] != 'z')
358     return 0;
359
360   p = c->augmentation + strlen (c->augmentation) + 1;
361
362   if (strcmp (c->augmentation, "eh") == 0)
363     {
364       c->eh_ptr = read_pointer (p);
365       p += sizeof (void *);
366     }
367   else
368     c->eh_ptr = 0;
369
370   p = decode_uleb128 (p, &c->code_align);
371   p = decode_sleb128 (p, &c->data_align);
372   c->ra_regno = *(unsigned char *)p++;
373
374   /* If the augmentation starts with 'z', we now see the length of the
375      augmentation fields.  */
376   if (c->augmentation[0] == 'z')
377     {
378       p = decode_uleb128 (p, &i);
379       p += i;
380     }
381
382   return p;
383 }
384
385 /* Decode one instruction's worth of of DWARF 2 call frame information.
386    Used by __frame_state_for.  Takes pointers P to the instruction to
387    decode, STATE to the current register unwind information, INFO to the
388    current CIE information, and PC to the current PC value.  Returns a
389    pointer to the next instruction.  */
390
391 static void *
392 execute_cfa_insn (void *p, struct frame_state_internal *state,
393                   struct cie_info *info, void **pc)
394 {
395   unsigned insn = *(unsigned char *)p++;
396   unsigned reg;
397   int offset;
398
399   if (insn & DW_CFA_advance_loc)
400     *pc += ((insn & 0x3f) * info->code_align);
401   else if (insn & DW_CFA_offset)
402     {
403       reg = (insn & 0x3f);
404       p = decode_uleb128 (p, &offset);
405       offset *= info->data_align;
406       state->s.saved[reg] = REG_SAVED_OFFSET;
407       state->s.reg_or_offset[reg] = offset;
408     }
409   else if (insn & DW_CFA_restore)
410     {
411       reg = (insn & 0x3f);
412       state->s.saved[reg] = REG_UNSAVED;
413     }
414   else switch (insn)
415     {
416     case DW_CFA_set_loc:
417       *pc = read_pointer (p);
418       p += sizeof (void *);
419       break;
420     case DW_CFA_advance_loc1:
421       *pc += read_1byte (p);
422       p += 1;
423       break;
424     case DW_CFA_advance_loc2:
425       *pc += read_2byte (p);
426       p += 2;
427       break;
428     case DW_CFA_advance_loc4:
429       *pc += read_4byte (p);
430       p += 4;
431       break;
432
433     case DW_CFA_offset_extended:
434       p = decode_uleb128 (p, &reg);
435       p = decode_uleb128 (p, &offset);
436       offset *= info->data_align;
437       state->s.saved[reg] = REG_SAVED_OFFSET;
438       state->s.reg_or_offset[reg] = offset;
439       break;
440     case DW_CFA_restore_extended:
441       p = decode_uleb128 (p, &reg);
442       state->s.saved[reg] = REG_UNSAVED;
443       break;
444
445     case DW_CFA_undefined:
446     case DW_CFA_same_value:
447     case DW_CFA_nop:
448       break;
449
450     case DW_CFA_register:
451       {
452         unsigned reg2;
453         p = decode_uleb128 (p, &reg);
454         p = decode_uleb128 (p, &reg2);
455         state->s.saved[reg] = REG_SAVED_REG;
456         state->s.reg_or_offset[reg] = reg2;
457       }
458       break;
459
460     case DW_CFA_def_cfa:
461       p = decode_uleb128 (p, &reg);
462       p = decode_uleb128 (p, &offset);
463       state->s.cfa_reg = reg;
464       state->s.cfa_offset = offset;
465       break;
466     case DW_CFA_def_cfa_register:
467       p = decode_uleb128 (p, &reg);
468       state->s.cfa_reg = reg;
469       break;
470     case DW_CFA_def_cfa_offset:
471       p = decode_uleb128 (p, &offset);
472       state->s.cfa_offset = offset;
473       break;
474       
475     case DW_CFA_remember_state:
476       {
477         struct frame_state_internal *save =
478           (struct frame_state_internal *)
479           malloc (sizeof (struct frame_state_internal));
480         memcpy (save, state, sizeof (struct frame_state_internal));
481         state->saved_state = save;
482       }
483       break;
484     case DW_CFA_restore_state:
485       {
486         struct frame_state_internal *save = state->saved_state;
487         memcpy (state, save, sizeof (struct frame_state_internal));
488         free (save);
489       }
490       break;
491
492       /* FIXME: Hardcoded for SPARC register window configuration.  */
493     case DW_CFA_GNU_window_save:
494       for (reg = 16; reg < 32; ++reg)
495         {
496           state->s.saved[reg] = REG_SAVED_OFFSET;
497           state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *);
498         }
499       break;
500
501     case DW_CFA_GNU_args_size:
502       p = decode_uleb128 (p, &offset);
503       state->s.args_size = offset;
504       break;
505
506     default:
507       abort ();
508     }
509   return p;
510 }
511 \f
512 /* Called from crtbegin.o to register the unwind info for an object.  */
513
514 void
515 __register_frame_info (void *begin, struct object *ob)
516 {
517   ob->fde_begin = begin;
518
519   ob->pc_begin = ob->pc_end = 0;
520   ob->fde_array = 0;
521   ob->count = 0;
522
523   __gthread_mutex_lock (&object_mutex);
524
525   ob->next = objects;
526   objects = ob;
527
528   __gthread_mutex_unlock (&object_mutex);
529 }
530
531 void
532 __register_frame (void *begin)
533 {
534   struct object *ob = (struct object *) malloc (sizeof (struct object));
535   __register_frame_info (begin, ob);                       
536 }
537
538 /* Similar, but BEGIN is actually a pointer to a table of unwind entries
539    for different translation units.  Called from the file generated by
540    collect2.  */
541
542 void
543 __register_frame_info_table (void *begin, struct object *ob)
544 {
545   ob->fde_begin = begin;
546   ob->fde_array = begin;
547
548   ob->pc_begin = ob->pc_end = 0;
549   ob->count = 0;
550
551   __gthread_mutex_lock (&object_mutex);
552
553   ob->next = objects;
554   objects = ob;
555
556   __gthread_mutex_unlock (&object_mutex);
557 }
558
559 void
560 __register_frame_table (void *begin)
561 {
562   struct object *ob = (struct object *) malloc (sizeof (struct object));
563   __register_frame_info_table (begin, ob);
564 }
565
566 /* Called from crtend.o to deregister the unwind info for an object.  */
567
568 void *
569 __deregister_frame_info (void *begin)
570 {
571   struct object **p;
572
573   __gthread_mutex_lock (&object_mutex);
574
575   p = &objects;
576   while (*p)
577     {
578       if ((*p)->fde_begin == begin)
579         {
580           struct object *ob = *p;
581           *p = (*p)->next;
582
583           /* If we've run init_frame for this object, free the FDE array.  */
584           if (ob->pc_begin)
585             free (ob->fde_array);
586
587           __gthread_mutex_unlock (&object_mutex);
588           return (void *) ob;
589         }
590       p = &((*p)->next);
591     }
592
593   __gthread_mutex_unlock (&object_mutex);
594   abort ();
595 }
596
597 void
598 __deregister_frame (void *begin)
599 {
600   free (__deregister_frame_info (begin));
601 }
602
603 /* Called from __throw to find the registers to restore for a given
604    PC_TARGET.  The caller should allocate a local variable of `struct
605    frame_state' (declared in frame.h) and pass its address to STATE_IN.  */
606
607 struct frame_state *
608 __frame_state_for (void *pc_target, struct frame_state *state_in)
609 {
610   fde *f;
611   void *insn, *end, *pc;
612   struct cie_info info;
613   struct frame_state_internal state;
614
615   f = find_fde (pc_target);
616   if (f == 0)
617     return 0;
618
619   insn = extract_cie_info (f, &info);
620   if (insn == 0)
621     return 0;
622
623   memset (&state, 0, sizeof (state));
624   state.s.retaddr_column = info.ra_regno;
625   state.s.eh_ptr = info.eh_ptr;
626
627   /* First decode all the insns in the CIE.  */
628   end = next_fde ((fde*) get_cie (f));
629   while (insn < end)
630     insn = execute_cfa_insn (insn, &state, &info, 0);
631
632   insn = ((fde *)f) + 1;
633
634   if (info.augmentation[0] == 'z')
635     {
636       int i;
637       insn = decode_uleb128 (insn, &i);
638       insn += i;
639     }
640
641   /* Then the insns in the FDE up to our target PC.  */
642   end = next_fde (f);
643   pc = f->pc_begin;
644   while (insn < end && pc <= pc_target)
645     insn = execute_cfa_insn (insn, &state, &info, &pc);
646
647   memcpy (state_in, &state.s, sizeof (state.s));
648   return state_in;
649 }
650 #endif /* DWARF2_UNWIND_INFO */