Back to index

glibc  2.9
unwind-dw2-fde.h
Go to the documentation of this file.
00001 /* Subroutines needed for unwinding stack frames for exception handling.  */
00002 /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
00003    Free Software Foundation, Inc.
00004    Contributed by Jason Merrill <jason@cygnus.com>.
00005 
00006    This file is part of the GNU C Library.
00007 
00008    The GNU C Library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2.1 of the License, or (at your option) any later version.
00012 
00013    The GNU C Library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with the GNU C Library; if not, write to the Free
00020    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00021    02111-1307 USA.  */
00022 
00023 
00024 struct fde_vector
00025 {
00026   void *orig_data;
00027   size_t count;
00028   struct dwarf_fde *array __flexarr;
00029 };
00030 
00031 #ifdef _LIBC
00032 #include <gccframe.h>
00033 #else
00034 struct object
00035 {
00036   void *pc_begin;
00037   void *tbase;
00038   void *dbase;
00039   union {
00040     struct dwarf_fde *single;
00041     struct dwarf_fde **array;
00042     struct fde_vector *sort;
00043   } u;
00044 
00045   union {
00046     struct {
00047       unsigned long sorted : 1;
00048       unsigned long from_array : 1;
00049       unsigned long mixed_encoding : 1;
00050       unsigned long encoding : 8;
00051       /* ??? Wish there was an easy way to detect a 64-bit host here;
00052         we've got 32 bits left to play with...  */
00053       unsigned long count : 21;
00054     } b;
00055     size_t i;
00056   } s;
00057 
00058 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
00059   char *fde_end;
00060 #endif
00061 
00062   struct object *next;
00063 };
00064 #endif
00065 
00066 /* This is the original definition of struct object.  While the struct
00067    itself was opaque to users, they did know how large it was, and
00068    allocate one statically in crtbegin for each DSO.  Keep this around
00069    so that we're aware of the static size limitations for the new struct.  */
00070 struct old_object
00071 {
00072   void *pc_begin;
00073   void *pc_end;
00074   struct dwarf_fde *fde_begin;
00075   struct dwarf_fde **fde_array;
00076   size_t count;
00077   struct old_object *next;
00078 };
00079 
00080 struct dwarf_eh_bases
00081 {
00082   void *tbase;
00083   void *dbase;
00084   void *func;
00085 };
00086 
00087 
00088 extern void __register_frame_info_bases (void *, struct object *,
00089                                     void *, void *);
00090 extern void __register_frame_info (void *, struct object *);
00091 extern void __register_frame (void *);
00092 extern void __register_frame_info_table_bases (void *, struct object *,
00093                                           void *, void *);
00094 extern void __register_frame_info_table (void *, struct object *);
00095 extern void __register_frame_table (void *);
00096 extern void *__deregister_frame_info (void *);
00097 extern void *__deregister_frame_info_bases (void *);
00098 extern void __deregister_frame (void *);
00099 
00100 
00101 typedef          int  sword __attribute__ ((mode (SI)));
00102 typedef unsigned int  uword __attribute__ ((mode (SI)));
00103 typedef unsigned int  uaddr __attribute__ ((mode (pointer)));
00104 typedef          int  saddr __attribute__ ((mode (pointer)));
00105 typedef unsigned char ubyte;
00106 
00107 /* Terminology:
00108    CIE - Common Information Element
00109    FDE - Frame Descriptor Element
00110 
00111    There is one per function, and it describes where the function code
00112    is located, and what the register lifetimes and stack layout are
00113    within the function.
00114 
00115    The data structures are defined in the DWARF specification, although
00116    not in a very readable way (see LITERATURE).
00117 
00118    Every time an exception is thrown, the code needs to locate the FDE
00119    for the current function, and starts to look for exception regions
00120    from that FDE. This works in a two-level search:
00121    a) in a linear search, find the shared image (i.e. DLL) containing
00122       the PC
00123    b) using the FDE table for that shared object, locate the FDE using
00124       binary search (which requires the sorting).  */
00125 
00126 /* The first few fields of a CIE.  The CIE_id field is 0 for a CIE,
00127    to distinguish it from a valid FDE.  FDEs are aligned to an addressing
00128    unit boundary, but the fields within are unaligned.  */
00129 struct dwarf_cie
00130 {
00131   uword length;
00132   sword CIE_id;
00133   ubyte version;
00134   unsigned char augmentation __flexarr;
00135 } __attribute__ ((packed, aligned (__alignof__ (void *))));
00136 
00137 /* The first few fields of an FDE.  */
00138 struct dwarf_fde
00139 {
00140   uword length;
00141   sword CIE_delta;
00142   unsigned char pc_begin __flexarr;
00143 } __attribute__ ((packed, aligned (__alignof__ (void *))));
00144 
00145 typedef struct dwarf_fde fde;
00146 
00147 /* Locate the CIE for a given FDE.  */
00148 
00149 static inline struct dwarf_cie *
00150 get_cie (struct dwarf_fde *f)
00151 {
00152   return (void *)&f->CIE_delta - f->CIE_delta;
00153 }
00154 
00155 static inline fde *
00156 next_fde (fde *f)
00157 {
00158   return (fde *) ((char *) f + f->length + sizeof (f->length));
00159 }
00160 
00161 extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
00162 
00163 static inline int
00164 last_fde (struct object *obj __attribute__ ((__unused__)), fde *f)
00165 {
00166 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
00167   return (char *)f == obj->fde_end || f->length == 0;
00168 #else
00169   return f->length == 0;
00170 #endif
00171 }