unwind-dw2-fde.h revision 90075
190075Sobrien/* Subroutines needed for unwinding stack frames for exception handling. */ 290075Sobrien/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 3290075Sobrien 3390075Sobrienstruct fde_vector 3490075Sobrien{ 3590075Sobrien void *orig_data; 3690075Sobrien size_t count; 3790075Sobrien struct dwarf_fde *array[]; 3890075Sobrien}; 3990075Sobrien 4090075Sobrienstruct object 4190075Sobrien{ 4290075Sobrien void *pc_begin; 4390075Sobrien void *tbase; 4490075Sobrien void *dbase; 4590075Sobrien union { 4690075Sobrien struct dwarf_fde *single; 4790075Sobrien struct dwarf_fde **array; 4890075Sobrien struct fde_vector *sort; 4990075Sobrien } u; 5090075Sobrien 5190075Sobrien union { 5290075Sobrien struct { 5390075Sobrien unsigned long sorted : 1; 5490075Sobrien unsigned long from_array : 1; 5590075Sobrien unsigned long mixed_encoding : 1; 5690075Sobrien unsigned long encoding : 8; 5790075Sobrien /* ??? Wish there was an easy way to detect a 64-bit host here; 5890075Sobrien we've got 32 bits left to play with... */ 5990075Sobrien unsigned long count : 21; 6090075Sobrien } b; 6190075Sobrien size_t i; 6290075Sobrien } s; 6390075Sobrien 6490075Sobrien struct object *next; 6590075Sobrien}; 6690075Sobrien 6790075Sobrien/* This is the original definition of struct object. While the struct 6890075Sobrien itself was opaque to users, they did know how large it was, and 6990075Sobrien allocate one statically in crtbegin for each DSO. Keep this around 7090075Sobrien so that we're aware of the static size limitations for the new struct. */ 7190075Sobrienstruct old_object 7290075Sobrien{ 7390075Sobrien void *pc_begin; 7490075Sobrien void *pc_end; 7590075Sobrien struct dwarf_fde *fde_begin; 7690075Sobrien struct dwarf_fde **fde_array; 7790075Sobrien size_t count; 7890075Sobrien struct old_object *next; 7990075Sobrien}; 8090075Sobrien 8190075Sobrienstruct dwarf_eh_bases 8290075Sobrien{ 8390075Sobrien void *tbase; 8490075Sobrien void *dbase; 8590075Sobrien void *func; 8690075Sobrien}; 8790075Sobrien 8890075Sobrien 8990075Sobrienextern void __register_frame_info_bases (void *, struct object *, 9090075Sobrien void *, void *); 9190075Sobrienextern void __register_frame_info (void *, struct object *); 9290075Sobrienextern void __register_frame (void *); 9390075Sobrienextern void __register_frame_info_table_bases (void *, struct object *, 9490075Sobrien void *, void *); 9590075Sobrienextern void __register_frame_info_table (void *, struct object *); 9690075Sobrienextern void __register_frame_table (void *); 9790075Sobrienextern void *__deregister_frame_info (void *); 9890075Sobrienextern void *__deregister_frame_info_bases (void *); 9990075Sobrienextern void __deregister_frame (void *); 10090075Sobrien 10190075Sobrien 10290075Sobrientypedef int sword __attribute__ ((mode (SI))); 10390075Sobrientypedef unsigned int uword __attribute__ ((mode (SI))); 10490075Sobrientypedef unsigned int uaddr __attribute__ ((mode (pointer))); 10590075Sobrientypedef int saddr __attribute__ ((mode (pointer))); 10690075Sobrientypedef unsigned char ubyte; 10790075Sobrien 10890075Sobrien/* Terminology: 10990075Sobrien CIE - Common Information Element 11090075Sobrien FDE - Frame Descriptor Element 11190075Sobrien 11290075Sobrien There is one per function, and it describes where the function code 11390075Sobrien is located, and what the register lifetimes and stack layout are 11490075Sobrien within the function. 11590075Sobrien 11690075Sobrien The data structures are defined in the DWARF specification, although 11790075Sobrien not in a very readable way (see LITERATURE). 11890075Sobrien 11990075Sobrien Every time an exception is thrown, the code needs to locate the FDE 12090075Sobrien for the current function, and starts to look for exception regions 12190075Sobrien from that FDE. This works in a two-level search: 12290075Sobrien a) in a linear search, find the shared image (i.e. DLL) containing 12390075Sobrien the PC 12490075Sobrien b) using the FDE table for that shared object, locate the FDE using 12590075Sobrien binary search (which requires the sorting). */ 12690075Sobrien 12790075Sobrien/* The first few fields of a CIE. The CIE_id field is 0 for a CIE, 12890075Sobrien to distinguish it from a valid FDE. FDEs are aligned to an addressing 12990075Sobrien unit boundary, but the fields within are unaligned. */ 13090075Sobrienstruct dwarf_cie 13190075Sobrien{ 13290075Sobrien uword length; 13390075Sobrien sword CIE_id; 13490075Sobrien ubyte version; 13590075Sobrien unsigned char augmentation[]; 13690075Sobrien} __attribute__ ((packed, aligned (__alignof__ (void *)))); 13790075Sobrien 13890075Sobrien/* The first few fields of an FDE. */ 13990075Sobrienstruct dwarf_fde 14090075Sobrien{ 14190075Sobrien uword length; 14290075Sobrien sword CIE_delta; 14390075Sobrien unsigned char pc_begin[]; 14490075Sobrien} __attribute__ ((packed, aligned (__alignof__ (void *)))); 14590075Sobrien 14690075Sobrientypedef struct dwarf_fde fde; 14790075Sobrien 14890075Sobrien/* Locate the CIE for a given FDE. */ 14990075Sobrien 15090075Sobrienstatic inline struct dwarf_cie * 15190075Sobrienget_cie (struct dwarf_fde *f) 15290075Sobrien{ 15390075Sobrien return (void *)&f->CIE_delta - f->CIE_delta; 15490075Sobrien} 15590075Sobrien 15690075Sobrienstatic inline fde * 15790075Sobriennext_fde (fde *f) 15890075Sobrien{ 15990075Sobrien return (fde *) ((char *) f + f->length + sizeof (f->length)); 16090075Sobrien} 16190075Sobrien 16290075Sobrienextern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *); 163