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