unwind-dw2-fde.h revision 132718
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 2990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 3090075Sobrien02111-1307, USA. */ 3190075Sobrien 32132718Skan#ifndef GCC_UNWIND_DW2_FDE_H 33132718Skan#define GCC_UNWIND_DW2_FDE_H 3490075Sobrien 3590075Sobrienstruct fde_vector 3690075Sobrien{ 37132718Skan const void *orig_data; 3890075Sobrien size_t count; 39132718Skan const struct dwarf_fde *array[]; 4090075Sobrien}; 4190075Sobrien 4290075Sobrienstruct object 4390075Sobrien{ 4490075Sobrien void *pc_begin; 4590075Sobrien void *tbase; 4690075Sobrien void *dbase; 4790075Sobrien union { 48132718Skan const struct dwarf_fde *single; 4990075Sobrien struct dwarf_fde **array; 5090075Sobrien struct fde_vector *sort; 5190075Sobrien } u; 5290075Sobrien 5390075Sobrien union { 5490075Sobrien struct { 5590075Sobrien unsigned long sorted : 1; 5690075Sobrien unsigned long from_array : 1; 5790075Sobrien unsigned long mixed_encoding : 1; 5890075Sobrien unsigned long encoding : 8; 5990075Sobrien /* ??? Wish there was an easy way to detect a 64-bit host here; 6090075Sobrien we've got 32 bits left to play with... */ 6190075Sobrien unsigned long count : 21; 6290075Sobrien } b; 6390075Sobrien size_t i; 6490075Sobrien } s; 6590075Sobrien 66117395Skan#ifdef DWARF2_OBJECT_END_PTR_EXTENSION 67117395Skan char *fde_end; 68117395Skan#endif 69117395Skan 7090075Sobrien struct object *next; 7190075Sobrien}; 7290075Sobrien 7390075Sobrien/* This is the original definition of struct object. While the struct 7490075Sobrien itself was opaque to users, they did know how large it was, and 7590075Sobrien allocate one statically in crtbegin for each DSO. Keep this around 7690075Sobrien so that we're aware of the static size limitations for the new struct. */ 7790075Sobrienstruct old_object 7890075Sobrien{ 7990075Sobrien void *pc_begin; 8090075Sobrien void *pc_end; 8190075Sobrien struct dwarf_fde *fde_begin; 8290075Sobrien struct dwarf_fde **fde_array; 8390075Sobrien size_t count; 8490075Sobrien struct old_object *next; 8590075Sobrien}; 8690075Sobrien 8790075Sobrienstruct dwarf_eh_bases 8890075Sobrien{ 8990075Sobrien void *tbase; 9090075Sobrien void *dbase; 9190075Sobrien void *func; 9290075Sobrien}; 9390075Sobrien 9490075Sobrien 95132718Skanextern void __register_frame_info_bases (const void *, struct object *, 9690075Sobrien void *, void *); 97132718Skanextern void __register_frame_info (const void *, struct object *); 9890075Sobrienextern void __register_frame (void *); 9990075Sobrienextern void __register_frame_info_table_bases (void *, struct object *, 10090075Sobrien void *, void *); 10190075Sobrienextern void __register_frame_info_table (void *, struct object *); 10290075Sobrienextern void __register_frame_table (void *); 103132718Skanextern void *__deregister_frame_info (const void *); 104132718Skanextern void *__deregister_frame_info_bases (const void *); 10590075Sobrienextern void __deregister_frame (void *); 10690075Sobrien 10790075Sobrien 10890075Sobrientypedef int sword __attribute__ ((mode (SI))); 10990075Sobrientypedef unsigned int uword __attribute__ ((mode (SI))); 11090075Sobrientypedef unsigned int uaddr __attribute__ ((mode (pointer))); 11190075Sobrientypedef int saddr __attribute__ ((mode (pointer))); 11290075Sobrientypedef unsigned char ubyte; 11390075Sobrien 11490075Sobrien/* Terminology: 11590075Sobrien CIE - Common Information Element 11690075Sobrien FDE - Frame Descriptor Element 11790075Sobrien 11890075Sobrien There is one per function, and it describes where the function code 11990075Sobrien is located, and what the register lifetimes and stack layout are 12090075Sobrien within the function. 12190075Sobrien 12290075Sobrien The data structures are defined in the DWARF specification, although 12390075Sobrien not in a very readable way (see LITERATURE). 12490075Sobrien 12590075Sobrien Every time an exception is thrown, the code needs to locate the FDE 12690075Sobrien for the current function, and starts to look for exception regions 12790075Sobrien from that FDE. This works in a two-level search: 12890075Sobrien a) in a linear search, find the shared image (i.e. DLL) containing 12990075Sobrien the PC 13090075Sobrien b) using the FDE table for that shared object, locate the FDE using 131117395Skan binary search (which requires the sorting). */ 13290075Sobrien 13390075Sobrien/* The first few fields of a CIE. The CIE_id field is 0 for a CIE, 13490075Sobrien to distinguish it from a valid FDE. FDEs are aligned to an addressing 13590075Sobrien unit boundary, but the fields within are unaligned. */ 13690075Sobrienstruct dwarf_cie 13790075Sobrien{ 13890075Sobrien uword length; 13990075Sobrien sword CIE_id; 14090075Sobrien ubyte version; 14190075Sobrien unsigned char augmentation[]; 14290075Sobrien} __attribute__ ((packed, aligned (__alignof__ (void *)))); 14390075Sobrien 14490075Sobrien/* The first few fields of an FDE. */ 14590075Sobrienstruct dwarf_fde 14690075Sobrien{ 14790075Sobrien uword length; 14890075Sobrien sword CIE_delta; 14990075Sobrien unsigned char pc_begin[]; 15090075Sobrien} __attribute__ ((packed, aligned (__alignof__ (void *)))); 15190075Sobrien 15290075Sobrientypedef struct dwarf_fde fde; 15390075Sobrien 15490075Sobrien/* Locate the CIE for a given FDE. */ 15590075Sobrien 156132718Skanstatic inline const struct dwarf_cie * 157132718Skanget_cie (const struct dwarf_fde *f) 15890075Sobrien{ 15990075Sobrien return (void *)&f->CIE_delta - f->CIE_delta; 16090075Sobrien} 16190075Sobrien 162132718Skanstatic inline const fde * 163132718Skannext_fde (const fde *f) 16490075Sobrien{ 165132718Skan return (const fde *) ((char *) f + f->length + sizeof (f->length)); 16690075Sobrien} 16790075Sobrien 168132718Skanextern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *); 169117395Skan 170117395Skanstatic inline int 171132718Skanlast_fde (struct object *obj __attribute__ ((__unused__)), const fde *f) 172117395Skan{ 173117395Skan#ifdef DWARF2_OBJECT_END_PTR_EXTENSION 174117395Skan return (char *)f == obj->fde_end || f->length == 0; 175117395Skan#else 176117395Skan return f->length == 0; 177117395Skan#endif 178117395Skan} 179132718Skan 180132718Skan#endif /* unwind-dw2-fde.h */ 181