190075Sobrien/* Subroutines needed for unwinding stack frames for exception handling.  */
2132718Skan/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
390075Sobrien   Free Software Foundation, Inc.
490075Sobrien   Contributed by Jason Merrill <jason@cygnus.com>.
590075Sobrien
690075SobrienThis file is part of GCC.
790075Sobrien
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1290075Sobrien
1390075SobrienIn addition to the permissions in the GNU General Public License, the
1490075SobrienFree Software Foundation gives you unlimited permission to link the
1590075Sobriencompiled version of this file into combinations with other programs,
1690075Sobrienand to distribute those combinations without any restriction coming
1790075Sobrienfrom the use of this file.  (The General Public License restrictions
1890075Sobriendo apply in other respects; for example, they cover modification of
1990075Sobrienthe file, and distribution when not linked into a combine
2090075Sobrienexecutable.)
2190075Sobrien
2290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
2390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
2490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2590075Sobrienfor more details.
2690075Sobrien
2790075SobrienYou should have received a copy of the GNU General Public License
2890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
29169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
30169689Skan02110-1301, USA.  */
3190075Sobrien
32132718Skan#ifndef GCC_UNWIND_DW2_FDE_H
33132718Skan#define GCC_UNWIND_DW2_FDE_H
3490075Sobrien
35169689Skan#ifndef HIDE_EXPORTS
36169689Skan#pragma GCC visibility push(default)
37169689Skan#endif
38169689Skan
3990075Sobrienstruct fde_vector
4090075Sobrien{
41132718Skan  const void *orig_data;
4290075Sobrien  size_t count;
43132718Skan  const struct dwarf_fde *array[];
4490075Sobrien};
4590075Sobrien
4690075Sobrienstruct object
4790075Sobrien{
4890075Sobrien  void *pc_begin;
4990075Sobrien  void *tbase;
5090075Sobrien  void *dbase;
5190075Sobrien  union {
52132718Skan    const struct dwarf_fde *single;
5390075Sobrien    struct dwarf_fde **array;
5490075Sobrien    struct fde_vector *sort;
5590075Sobrien  } u;
5690075Sobrien
5790075Sobrien  union {
5890075Sobrien    struct {
5990075Sobrien      unsigned long sorted : 1;
6090075Sobrien      unsigned long from_array : 1;
6190075Sobrien      unsigned long mixed_encoding : 1;
6290075Sobrien      unsigned long encoding : 8;
6390075Sobrien      /* ??? Wish there was an easy way to detect a 64-bit host here;
6490075Sobrien	 we've got 32 bits left to play with...  */
6590075Sobrien      unsigned long count : 21;
6690075Sobrien    } b;
6790075Sobrien    size_t i;
6890075Sobrien  } s;
6990075Sobrien
70117395Skan#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
71117395Skan  char *fde_end;
72117395Skan#endif
73117395Skan
7490075Sobrien  struct object *next;
7590075Sobrien};
7690075Sobrien
7790075Sobrien/* This is the original definition of struct object.  While the struct
7890075Sobrien   itself was opaque to users, they did know how large it was, and
7990075Sobrien   allocate one statically in crtbegin for each DSO.  Keep this around
8090075Sobrien   so that we're aware of the static size limitations for the new struct.  */
8190075Sobrienstruct old_object
8290075Sobrien{
8390075Sobrien  void *pc_begin;
8490075Sobrien  void *pc_end;
8590075Sobrien  struct dwarf_fde *fde_begin;
8690075Sobrien  struct dwarf_fde **fde_array;
8790075Sobrien  size_t count;
8890075Sobrien  struct old_object *next;
8990075Sobrien};
9090075Sobrien
9190075Sobrienstruct dwarf_eh_bases
9290075Sobrien{
9390075Sobrien  void *tbase;
9490075Sobrien  void *dbase;
9590075Sobrien  void *func;
9690075Sobrien};
9790075Sobrien
9890075Sobrien
99132718Skanextern void __register_frame_info_bases (const void *, struct object *,
10090075Sobrien					 void *, void *);
101132718Skanextern void __register_frame_info (const void *, struct object *);
10290075Sobrienextern void __register_frame (void *);
10390075Sobrienextern void __register_frame_info_table_bases (void *, struct object *,
10490075Sobrien					       void *, void *);
10590075Sobrienextern void __register_frame_info_table (void *, struct object *);
10690075Sobrienextern void __register_frame_table (void *);
107132718Skanextern void *__deregister_frame_info (const void *);
108132718Skanextern void *__deregister_frame_info_bases (const void *);
10990075Sobrienextern void __deregister_frame (void *);
11090075Sobrien
11190075Sobrien
11290075Sobrientypedef          int  sword __attribute__ ((mode (SI)));
11390075Sobrientypedef unsigned int  uword __attribute__ ((mode (SI)));
11490075Sobrientypedef unsigned int  uaddr __attribute__ ((mode (pointer)));
11590075Sobrientypedef          int  saddr __attribute__ ((mode (pointer)));
11690075Sobrientypedef unsigned char ubyte;
11790075Sobrien
11890075Sobrien/* Terminology:
11990075Sobrien   CIE - Common Information Element
12090075Sobrien   FDE - Frame Descriptor Element
12190075Sobrien
12290075Sobrien   There is one per function, and it describes where the function code
12390075Sobrien   is located, and what the register lifetimes and stack layout are
12490075Sobrien   within the function.
12590075Sobrien
12690075Sobrien   The data structures are defined in the DWARF specification, although
12790075Sobrien   not in a very readable way (see LITERATURE).
12890075Sobrien
12990075Sobrien   Every time an exception is thrown, the code needs to locate the FDE
13090075Sobrien   for the current function, and starts to look for exception regions
13190075Sobrien   from that FDE. This works in a two-level search:
13290075Sobrien   a) in a linear search, find the shared image (i.e. DLL) containing
13390075Sobrien      the PC
13490075Sobrien   b) using the FDE table for that shared object, locate the FDE using
135117395Skan      binary search (which requires the sorting).  */
13690075Sobrien
13790075Sobrien/* The first few fields of a CIE.  The CIE_id field is 0 for a CIE,
13890075Sobrien   to distinguish it from a valid FDE.  FDEs are aligned to an addressing
13990075Sobrien   unit boundary, but the fields within are unaligned.  */
14090075Sobrienstruct dwarf_cie
14190075Sobrien{
14290075Sobrien  uword length;
14390075Sobrien  sword CIE_id;
14490075Sobrien  ubyte version;
14590075Sobrien  unsigned char augmentation[];
14690075Sobrien} __attribute__ ((packed, aligned (__alignof__ (void *))));
14790075Sobrien
14890075Sobrien/* The first few fields of an FDE.  */
14990075Sobrienstruct dwarf_fde
15090075Sobrien{
15190075Sobrien  uword length;
15290075Sobrien  sword CIE_delta;
15390075Sobrien  unsigned char pc_begin[];
15490075Sobrien} __attribute__ ((packed, aligned (__alignof__ (void *))));
15590075Sobrien
15690075Sobrientypedef struct dwarf_fde fde;
15790075Sobrien
15890075Sobrien/* Locate the CIE for a given FDE.  */
15990075Sobrien
160132718Skanstatic inline const struct dwarf_cie *
161132718Skanget_cie (const struct dwarf_fde *f)
16290075Sobrien{
16390075Sobrien  return (void *)&f->CIE_delta - f->CIE_delta;
16490075Sobrien}
16590075Sobrien
166132718Skanstatic inline const fde *
167132718Skannext_fde (const fde *f)
16890075Sobrien{
169132718Skan  return (const fde *) ((char *) f + f->length + sizeof (f->length));
17090075Sobrien}
17190075Sobrien
172132718Skanextern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
173117395Skan
174117395Skanstatic inline int
175132718Skanlast_fde (struct object *obj __attribute__ ((__unused__)), const fde *f)
176117395Skan{
177117395Skan#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
178117395Skan  return (char *)f == obj->fde_end || f->length == 0;
179117395Skan#else
180117395Skan  return f->length == 0;
181117395Skan#endif
182117395Skan}
183132718Skan
184169689Skan#ifndef HIDE_EXPORTS
185169689Skan#pragma GCC visibility pop
186169689Skan#endif
187169689Skan
188132718Skan#endif /* unwind-dw2-fde.h */
189