Blame sysdeps/generic/unwind-dw2-fde.h

Packit Service 82fcde
/* Subroutines needed for unwinding stack frames for exception handling.  */
Packit Service 82fcde
/* Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   Contributed by Jason Merrill <jason@cygnus.com>.
Packit Service 82fcde
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
struct fde_vector
Packit Service 82fcde
{
Packit Service 82fcde
  void *orig_data;
Packit Service 82fcde
  size_t count;
Packit Service 82fcde
  struct dwarf_fde *array __flexarr;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
#include <gccframe.h>
Packit Service 82fcde
#else
Packit Service 82fcde
struct object
Packit Service 82fcde
{
Packit Service 82fcde
  void *pc_begin;
Packit Service 82fcde
  void *tbase;
Packit Service 82fcde
  void *dbase;
Packit Service 82fcde
  union {
Packit Service 82fcde
    struct dwarf_fde *single;
Packit Service 82fcde
    struct dwarf_fde **array;
Packit Service 82fcde
    struct fde_vector *sort;
Packit Service 82fcde
  } u;
Packit Service 82fcde
Packit Service 82fcde
  union {
Packit Service 82fcde
    struct {
Packit Service 82fcde
      unsigned long sorted : 1;
Packit Service 82fcde
      unsigned long from_array : 1;
Packit Service 82fcde
      unsigned long mixed_encoding : 1;
Packit Service 82fcde
      unsigned long encoding : 8;
Packit Service 82fcde
      /* ??? Wish there was an easy way to detect a 64-bit host here;
Packit Service 82fcde
	 we've got 32 bits left to play with...  */
Packit Service 82fcde
      unsigned long count : 21;
Packit Service 82fcde
    } b;
Packit Service 82fcde
    size_t i;
Packit Service 82fcde
  } s;
Packit Service 82fcde
Packit Service 82fcde
#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
Packit Service 82fcde
  char *fde_end;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  struct object *next;
Packit Service 82fcde
};
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* This is the original definition of struct object.  While the struct
Packit Service 82fcde
   itself was opaque to users, they did know how large it was, and
Packit Service 82fcde
   allocate one statically in crtbegin for each DSO.  Keep this around
Packit Service 82fcde
   so that we're aware of the static size limitations for the new struct.  */
Packit Service 82fcde
struct old_object
Packit Service 82fcde
{
Packit Service 82fcde
  void *pc_begin;
Packit Service 82fcde
  void *pc_end;
Packit Service 82fcde
  struct dwarf_fde *fde_begin;
Packit Service 82fcde
  struct dwarf_fde **fde_array;
Packit Service 82fcde
  size_t count;
Packit Service 82fcde
  struct old_object *next;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
struct dwarf_eh_bases
Packit Service 82fcde
{
Packit Service 82fcde
  void *tbase;
Packit Service 82fcde
  void *dbase;
Packit Service 82fcde
  void *func;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
extern void __register_frame_info_bases (void *, struct object *,
Packit Service 82fcde
					 void *, void *);
Packit Service 82fcde
extern void __register_frame_info (void *, struct object *);
Packit Service 82fcde
extern void __register_frame (void *);
Packit Service 82fcde
extern void __register_frame_info_table_bases (void *, struct object *,
Packit Service 82fcde
					       void *, void *);
Packit Service 82fcde
extern void __register_frame_info_table (void *, struct object *);
Packit Service 82fcde
extern void __register_frame_table (void *);
Packit Service 82fcde
extern void *__deregister_frame_info (void *);
Packit Service 82fcde
extern void *__deregister_frame_info_bases (void *);
Packit Service 82fcde
extern void __deregister_frame (void *);
Packit Service 82fcde
Packit Service 82fcde

Packit Service 82fcde
typedef          int  sword __attribute__ ((mode (SI)));
Packit Service 82fcde
typedef unsigned int  uword __attribute__ ((mode (SI)));
Packit Service 82fcde
typedef unsigned int  uaddr __attribute__ ((mode (pointer)));
Packit Service 82fcde
typedef          int  saddr __attribute__ ((mode (pointer)));
Packit Service 82fcde
typedef unsigned char ubyte;
Packit Service 82fcde
Packit Service 82fcde
/* Terminology:
Packit Service 82fcde
   CIE - Common Information Element
Packit Service 82fcde
   FDE - Frame Descriptor Element
Packit Service 82fcde
Packit Service 82fcde
   There is one per function, and it describes where the function code
Packit Service 82fcde
   is located, and what the register lifetimes and stack layout are
Packit Service 82fcde
   within the function.
Packit Service 82fcde
Packit Service 82fcde
   The data structures are defined in the DWARF specification, although
Packit Service 82fcde
   not in a very readable way (see LITERATURE).
Packit Service 82fcde
Packit Service 82fcde
   Every time an exception is thrown, the code needs to locate the FDE
Packit Service 82fcde
   for the current function, and starts to look for exception regions
Packit Service 82fcde
   from that FDE. This works in a two-level search:
Packit Service 82fcde
   a) in a linear search, find the shared image (i.e. DLL) containing
Packit Service 82fcde
      the PC
Packit Service 82fcde
   b) using the FDE table for that shared object, locate the FDE using
Packit Service 82fcde
      binary search (which requires the sorting).  */
Packit Service 82fcde
Packit Service 82fcde
/* The first few fields of a CIE.  The CIE_id field is 0 for a CIE,
Packit Service 82fcde
   to distinguish it from a valid FDE.  FDEs are aligned to an addressing
Packit Service 82fcde
   unit boundary, but the fields within are unaligned.  */
Packit Service 82fcde
struct dwarf_cie
Packit Service 82fcde
{
Packit Service 82fcde
  uword length;
Packit Service 82fcde
  sword CIE_id;
Packit Service 82fcde
  ubyte version;
Packit Service 82fcde
  unsigned char augmentation __flexarr;
Packit Service 82fcde
} __attribute__ ((packed, aligned (__alignof__ (void *))));
Packit Service 82fcde
Packit Service 82fcde
/* The first few fields of an FDE.  */
Packit Service 82fcde
struct dwarf_fde
Packit Service 82fcde
{
Packit Service 82fcde
  uword length;
Packit Service 82fcde
  sword CIE_delta;
Packit Service 82fcde
  unsigned char pc_begin __flexarr;
Packit Service 82fcde
} __attribute__ ((packed, aligned (__alignof__ (void *))));
Packit Service 82fcde
Packit Service 82fcde
typedef struct dwarf_fde fde;
Packit Service 82fcde
Packit Service 82fcde
/* Locate the CIE for a given FDE.  */
Packit Service 82fcde
Packit Service 82fcde
static inline struct dwarf_cie *
Packit Service 82fcde
get_cie (struct dwarf_fde *f)
Packit Service 82fcde
{
Packit Service 82fcde
  return (void *)&f->CIE_delta - f->CIE_delta;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static inline fde *
Packit Service 82fcde
next_fde (fde *f)
Packit Service 82fcde
{
Packit Service 82fcde
  return (fde *) ((char *) f + f->length + sizeof (f->length));
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
last_fde (struct object *obj __attribute__ ((__unused__)), fde *f)
Packit Service 82fcde
{
Packit Service 82fcde
#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
Packit Service 82fcde
  return (char *)f == obj->fde_end || f->length == 0;
Packit Service 82fcde
#else
Packit Service 82fcde
  return f->length == 0;
Packit Service 82fcde
#endif
Packit Service 82fcde
}