PATCH: Add __frame_state_for for gcc 3.0.1
H . J . Lu
hjl@lucon.org
Thu Jul 5 09:33:00 GMT 2001
On Thu, Jul 05, 2001 at 10:17:02AM +0200, Jakub Jelinek wrote:
> On Wed, Jul 04, 2001 at 11:32:17PM -0700, H . J . Lu wrote:
> > Here is a new patch. glibc has to export __register_frame_info_bases,
> > __deregister_frame_info_bases and __register_frame_info_table_bases with
> > version GCC_3.0 since that is what is in libgcc_s.so.1.
> >
> > Now it passed "make check" in glibc built with gcc 3.0.1 and gcc 2.96.
>
>
> Now to whether GLIBC should export the (de)register and _Unwind_Find_FDE
> routines at all, I'll repeat myself here; the options are IMHO:
> - it should not (neither old __register_frame_info and older interfaces,
> just __frame_state_for on arches which need it) - then glibc needs
Yes, the key is we can only have one copy of those functions. It
is an all or nothing deal.
> libgcc_s.so.1 as either DT_NEEDED or DT_FILTER (the latter only in the
> current GLIBC DT_FILTER handling, would not work in Solaris DT_FILTER
> semantics)
> - it should (then again, all the registration routines and _Unwind_Find_FDE
> need to be exported from the same place, where the same place can be both
> libc.so.6 and libgcc_s.so.1). libgcc_s.so.1 is either not needed by
> libc.so.6 at all, or is DT_AUXILIARY with GLIBC semantics.
> I strongly favour the latter. It means small non-C++ non-Java programs will
Me too, for the same reasons.
> not be slowed down by yet another shared library (thus increasing memory
> footprint a lot, plus adding overhead at startup time).
> It would mean the system compiler (where system compiler is the compiler
> which usually vendor provided and which was used to compile GLIBC) can
> default to -static-libgcc for non-C++ non-Java shared libraries, so
> libgcc_s.so.1 overhead would come up only for shared libraries which really
> need it (where need it is not just that they are linked with crtbeginS.o
> which needs __register_frame_info_bases, since that one is provided by
> glibc). How would this work for Joe random user installing a later GCC
> version on his own? Well, easily. The non-system GCC would default to
> -shared-libgcc as it does currently, so the possibly updated (versioned)
I think the current gcc default to -shared-libgcc for DSOs and
-static-libgcc for executables. It is ok for non-C++/Java
executables. But -shared-libgcc may be needed for C++/Java
executables.
> As far as IA-64 is concerned, IMHO _Unwind_FindTableEntry should be exported
> both from libgcc_s.so.1 and GLIBC. libgcc_s.so.1 implementation will
> definitely need some kind of for_each_fde interface, GLIBC can either just
> pick it up from libgcc.a and export, or come with its own, somewhat optimized
> as it knows the internals, version.
Someone has to add the ia64 support. I left out the hurd support.
It should be trivial to add once the whole thing is settled down.
>
> I think the important part of the patch now is really the missing DW_EH_PE_*
> handling stuff.
I can always abort -). Does it only happen when a pre-G++ 3.0
binary throw an exception inside libc.so?
> As far as gcc-2.96-RH (well, gcc <= 2.96-84 particularly) binary
> compatibility is concerned, once you have final version of the patch I can
> split it into standard GLIBC patch and Red Hat local GLIBC patch (well, I
> think Mandrake and some others are interested in that too).
>
Here is a minor update which exports _Unwind_Find_FDE and
adds the conditional support for gcc 3.0.
Thanks.
H.J.
-----
2001-07-05 H.J. Lu <hjl@gnu.org>
* Versions.def (libc): Add GCC_3.0 if needed.
* config.h.in (HAVE_DWARF2_UNWIND_GCC_3): Added.
(HAVE_UNWIND_FIND_FDE): Added.
* sysdeps/unix/sysv/linux/Versions (libc): Add _Unwind_Find_FDE,
__register_frame_info_bases, __deregister_frame_info_bases and
__register_frame_info_table_bases to version GCC_3.0 if needed.
* config.make.in (need-frame-dwarf2): New. Substitute by
@libc_cv_frame_dwarf2@.
* configure.in (libc_cv_frame_dwarf2): Set to yes if
_Unwind_Find_FDE exists in libgcc.
(HAVE_UNWIND_FIND_FDE): Define if _Unwind_Find_FDE exists in
libgcc.
(HAVE_DWARF2_UNWIND_GCC_3): Define for gcc 3 version of DWARF2
unwind.
* configure: Rebuild.
* sysdeps/generic/dwarf2.h: New file.
* sysdeps/generic/frame-dwarf2.c: Likewise.
* sysdeps/alpha/gccframe.h: Likewise.
* sysdeps/arm/gccframe.h: Likewise.
* sysdeps/i386/gccframe.h: Likewise.
* sysdeps/m68k/gccframe.h: Likewise.
* sysdeps/mips/gccframe.h: Likewise.
* sysdeps/powerpc/gccframe.h: Likewise.
* sysdeps/s390/s390-32/gccframe.h: Likewise.
* sysdeps/sparc/gccframe.h: Likewise.
* sysdeps/generic/gccframe.h: Updated.
* sysdeps/unix/sysv/linux/alpha/Makefile (sysdep_routines): Add
frame-dwarf2 for elf if $(build-shared) and $(need-frame-dwarf2)
are both yes.
(shared-only-routines): Likewise.
* sysdeps/unix/sysv/linux/arm/Makefile: Likewise.
* sysdeps/unix/sysv/linux/i386/Makefile: Likewise.
* sysdeps/unix/sysv/linux/m68k/Makefile: Likewise.
* sysdeps/unix/sysv/linux/mips/Makefile: Likewise.
* sysdeps/unix/sysv/linux/powerpc/Makefile: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/Makefile: Likewise.
* sysdeps/unix/sysv/linux/sparc/Makefile: Likewise.
--- libc/Versions.def.gcc Fri Jun 1 20:36:08 2001
+++ libc/Versions.def Thu Jul 5 08:52:38 2001
@@ -16,6 +16,9 @@ libc {
%ifdef USE_IN_LIBIO
HURD_CTHREADS_0.3
%endif
+%ifdef HAVE_DWARF2_UNWIND_GCC_3
+ GCC_3.0
+%endif
}
libcrypt {
GLIBC_2.0
--- libc/config.h.in.gcc Mon Mar 19 10:36:15 2001
+++ libc/config.h.in Thu Jul 5 09:04:22 2001
@@ -72,6 +72,13 @@
with static variable. */
#undef HAVE_DWARF2_UNWIND_INFO_STATIC
+/* Define if the gcc v3 DWARF2 unwind information for exception support
+ is used. */
+#undef HAVE_DWARF2_UNWIND_GCC_3
+
+/* Define if _Unwind_Find_FDE is in libgcc.a. */
+#undef HAVE_UNWIND_FIND_FDE
+
/* Define if the compiler supports __builtin_expect. */
#undef HAVE_BUILTIN_EXPECT
--- libc/config.make.in.gcc Mon Mar 19 10:36:15 2001
+++ libc/config.make.in Wed Jul 4 21:37:33 2001
@@ -46,6 +46,8 @@ need-nopic-initfini = @nopic_initfini@
with-cvs = @with_cvs@
old-glibc-headers = @old_glibc_headers@
+need-frame-dwarf2 = @libc_cv_frame_dwarf2@
+
versioning = @VERSIONING@
oldest-abi = @oldest_abi@
no-whole-archive = @no_whole_archive@
--- libc/configure.in.gcc Sat Jun 16 15:32:37 2001
+++ libc/configure.in Thu Jul 5 09:12:05 2001
@@ -1318,6 +1318,26 @@ static)
;;
esac
+AC_CACHE_CHECK(for gcc 3 version of DWARF2 unwind,
+ libc_cv_dwarf2_unwind_gcc_3,
+ [AC_TRY_LINK([extern void __register_frame_info_table_bases ();],
+ [__register_frame_info_table_bases ();],
+ libc_cv_dwarf2_unwind_gcc_3=yes,
+ libc_cv_dwarf2_unwind_gcc_3=no)])
+if test $libc_cv_dwarf2_unwind_gcc_3 = yes; then
+ AC_DEFINE(HAVE_DWARF2_UNWIND_GCC_3)
+fi
+
+AC_CACHE_CHECK(for _Unwind_Find_FDE in libgcc, libc_cv_frame_dwarf2,
+ [AC_TRY_LINK([extern void _Unwind_Find_FDE ();],
+ [_Unwind_Find_FDE ();],
+ libc_cv_frame_dwarf2=yes,
+ libc_cv_frame_dwarf2=no)])
+AC_SUBST(libc_cv_frame_dwarf2)
+if test $libc_cv_frame_dwarf2 = yes; then
+ AC_DEFINE(HAVE_UNWIND_FIND_FDE)
+fi
+
dnl Check whether compiler understands __builtin_expect.
AC_CACHE_CHECK(for __builtin_expect, libc_cv_gcc_builtin_expect,
[cat > conftest.c <<EOF
--- libc/sysdeps/alpha/gccframe.h.gcc Wed Jul 4 21:37:33 2001
+++ libc/sysdeps/alpha/gccframe.h Wed Jul 4 21:37:33 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define FIRST_PSEUDO_REGISTER 64
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/arm/gccframe.h.gcc Wed Jul 4 21:37:33 2001
+++ libc/sysdeps/arm/gccframe.h Wed Jul 4 21:37:33 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define FIRST_PSEUDO_REGISTER 27
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/generic/dwarf2.h.gcc Wed Jul 4 21:37:33 2001
+++ libc/sysdeps/generic/dwarf2.h Wed Jul 4 21:37:33 2001
@@ -0,0 +1,553 @@
+/* Declarations and definitions of codes relating to the DWARF2 symbolic
+ debugging information format.
+ Copyright (C) 1992, 1993, 1995, 1996, 1997, 2000
+ Free Software Foundation, Inc.
+ Contributed by Gary Funck (gary@intrepid.com). Derived from the
+ DWARF 1 implementation written by Ron Guilmette (rfg@monkeys.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This file is derived from the DWARF specification (a public document)
+ Revision 2.0.0 (July 27, 1993) developed by the UNIX International
+ Programming Languages Special Interest Group (UI/PLSIG) and distributed
+ by UNIX International. Copies of this specification are available from
+ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */
+
+/* This file is shared between GCC and GDB, and should not contain
+ prototypes. */
+
+/* Tag names and codes. */
+
+enum dwarf_tag
+ {
+ DW_TAG_padding = 0x00,
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_param = 0x2f,
+ DW_TAG_template_value_param = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ /* SGI/MIPS Extensions */
+ DW_TAG_MIPS_loop = 0x4081,
+ /* GNU extensions */
+ DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */
+ DW_TAG_function_template = 0x4102, /* for C++ */
+ DW_TAG_class_template = 0x4103 /* for C++ */
+ };
+
+#define DW_TAG_lo_user 0x4080
+#define DW_TAG_hi_user 0xffff
+
+/* flag that tells whether entry has a child or not */
+#define DW_children_no 0
+#define DW_children_yes 1
+
+/* Form names and codes. */
+enum dwarf_form
+ {
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16
+ };
+
+/* Attribute names and codes. */
+
+enum dwarf_attribute
+ {
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_subscr_data = 0x0a,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_element_list = 0x0f,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_member = 0x14,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_stride_size = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_items = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ /* SGI/MIPS Extensions */
+ DW_AT_MIPS_fde = 0x2001,
+ DW_AT_MIPS_loop_begin = 0x2002,
+ DW_AT_MIPS_tail_loop_begin = 0x2003,
+ DW_AT_MIPS_epilog_begin = 0x2004,
+ DW_AT_MIPS_loop_unroll_factor = 0x2005,
+ DW_AT_MIPS_software_pipeline_depth = 0x2006,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_MIPS_stride = 0x2008,
+ DW_AT_MIPS_abstract_name = 0x2009,
+ DW_AT_MIPS_clone_origin = 0x200a,
+ DW_AT_MIPS_has_inlines = 0x200b,
+ /* GNU extensions. */
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106
+ };
+
+#define DW_AT_lo_user 0x2000 /* implementation-defined range start */
+#define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */
+
+/* Location atom names and codes. */
+
+enum dwarf_location_atom
+ {
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_skip = 0x2f,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit2 = 0x32,
+ DW_OP_lit3 = 0x33,
+ DW_OP_lit4 = 0x34,
+ DW_OP_lit5 = 0x35,
+ DW_OP_lit6 = 0x36,
+ DW_OP_lit7 = 0x37,
+ DW_OP_lit8 = 0x38,
+ DW_OP_lit9 = 0x39,
+ DW_OP_lit10 = 0x3a,
+ DW_OP_lit11 = 0x3b,
+ DW_OP_lit12 = 0x3c,
+ DW_OP_lit13 = 0x3d,
+ DW_OP_lit14 = 0x3e,
+ DW_OP_lit15 = 0x3f,
+ DW_OP_lit16 = 0x40,
+ DW_OP_lit17 = 0x41,
+ DW_OP_lit18 = 0x42,
+ DW_OP_lit19 = 0x43,
+ DW_OP_lit20 = 0x44,
+ DW_OP_lit21 = 0x45,
+ DW_OP_lit22 = 0x46,
+ DW_OP_lit23 = 0x47,
+ DW_OP_lit24 = 0x48,
+ DW_OP_lit25 = 0x49,
+ DW_OP_lit26 = 0x4a,
+ DW_OP_lit27 = 0x4b,
+ DW_OP_lit28 = 0x4c,
+ DW_OP_lit29 = 0x4d,
+ DW_OP_lit30 = 0x4e,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg2 = 0x52,
+ DW_OP_reg3 = 0x53,
+ DW_OP_reg4 = 0x54,
+ DW_OP_reg5 = 0x55,
+ DW_OP_reg6 = 0x56,
+ DW_OP_reg7 = 0x57,
+ DW_OP_reg8 = 0x58,
+ DW_OP_reg9 = 0x59,
+ DW_OP_reg10 = 0x5a,
+ DW_OP_reg11 = 0x5b,
+ DW_OP_reg12 = 0x5c,
+ DW_OP_reg13 = 0x5d,
+ DW_OP_reg14 = 0x5e,
+ DW_OP_reg15 = 0x5f,
+ DW_OP_reg16 = 0x60,
+ DW_OP_reg17 = 0x61,
+ DW_OP_reg18 = 0x62,
+ DW_OP_reg19 = 0x63,
+ DW_OP_reg20 = 0x64,
+ DW_OP_reg21 = 0x65,
+ DW_OP_reg22 = 0x66,
+ DW_OP_reg23 = 0x67,
+ DW_OP_reg24 = 0x68,
+ DW_OP_reg25 = 0x69,
+ DW_OP_reg26 = 0x6a,
+ DW_OP_reg27 = 0x6b,
+ DW_OP_reg28 = 0x6c,
+ DW_OP_reg29 = 0x6d,
+ DW_OP_reg30 = 0x6e,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg2 = 0x72,
+ DW_OP_breg3 = 0x73,
+ DW_OP_breg4 = 0x74,
+ DW_OP_breg5 = 0x75,
+ DW_OP_breg6 = 0x76,
+ DW_OP_breg7 = 0x77,
+ DW_OP_breg8 = 0x78,
+ DW_OP_breg9 = 0x79,
+ DW_OP_breg10 = 0x7a,
+ DW_OP_breg11 = 0x7b,
+ DW_OP_breg12 = 0x7c,
+ DW_OP_breg13 = 0x7d,
+ DW_OP_breg14 = 0x7e,
+ DW_OP_breg15 = 0x7f,
+ DW_OP_breg16 = 0x80,
+ DW_OP_breg17 = 0x81,
+ DW_OP_breg18 = 0x82,
+ DW_OP_breg19 = 0x83,
+ DW_OP_breg20 = 0x84,
+ DW_OP_breg21 = 0x85,
+ DW_OP_breg22 = 0x86,
+ DW_OP_breg23 = 0x87,
+ DW_OP_breg24 = 0x88,
+ DW_OP_breg25 = 0x89,
+ DW_OP_breg26 = 0x8a,
+ DW_OP_breg27 = 0x8b,
+ DW_OP_breg28 = 0x8c,
+ DW_OP_breg29 = 0x8d,
+ DW_OP_breg30 = 0x8e,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96
+ };
+
+#define DW_OP_lo_user 0x80 /* implementation-defined range start */
+#define DW_OP_hi_user 0xff /* implementation-defined range end */
+
+/* Type encodings. */
+
+enum dwarf_type
+ {
+ DW_ATE_void = 0x0,
+ DW_ATE_address = 0x1,
+ DW_ATE_boolean = 0x2,
+ DW_ATE_complex_float = 0x3,
+ DW_ATE_float = 0x4,
+ DW_ATE_signed = 0x5,
+ DW_ATE_signed_char = 0x6,
+ DW_ATE_unsigned = 0x7,
+ DW_ATE_unsigned_char = 0x8
+ };
+
+#define DW_ATE_lo_user 0x80
+#define DW_ATE_hi_user 0xff
+
+/* Array ordering names and codes. */
+enum dwarf_array_dim_ordering
+ {
+ DW_ORD_row_major = 0,
+ DW_ORD_col_major = 1
+ };
+
+/* access attribute */
+enum dwarf_access_attribute
+ {
+ DW_ACCESS_public = 1,
+ DW_ACCESS_protected = 2,
+ DW_ACCESS_private = 3
+ };
+
+/* visibility */
+enum dwarf_visibility_attribute
+ {
+ DW_VIS_local = 1,
+ DW_VIS_exported = 2,
+ DW_VIS_qualified = 3
+ };
+
+/* virtuality */
+enum dwarf_virtuality_attribute
+ {
+ DW_VIRTUALITY_none = 0,
+ DW_VIRTUALITY_virtual = 1,
+ DW_VIRTUALITY_pure_virtual = 2
+ };
+
+/* case sensitivity */
+enum dwarf_id_case
+ {
+ DW_ID_case_sensitive = 0,
+ DW_ID_up_case = 1,
+ DW_ID_down_case = 2,
+ DW_ID_case_insensitive = 3
+ };
+
+/* calling convention */
+enum dwarf_calling_convention
+ {
+ DW_CC_normal = 0x1,
+ DW_CC_program = 0x2,
+ DW_CC_nocall = 0x3
+ };
+
+#define DW_CC_lo_user 0x40
+#define DW_CC_hi_user 0xff
+
+/* inline attribute */
+enum dwarf_inline_attribute
+ {
+ DW_INL_not_inlined = 0,
+ DW_INL_inlined = 1,
+ DW_INL_declared_not_inlined = 2,
+ DW_INL_declared_inlined = 3
+ };
+
+/* discriminant lists */
+enum dwarf_discrim_list
+ {
+ DW_DSC_label = 0,
+ DW_DSC_range = 1
+ };
+
+/* line number opcodes */
+enum dwarf_line_number_ops
+ {
+ DW_LNS_extended_op = 0,
+ DW_LNS_copy = 1,
+ DW_LNS_advance_pc = 2,
+ DW_LNS_advance_line = 3,
+ DW_LNS_set_file = 4,
+ DW_LNS_set_column = 5,
+ DW_LNS_negate_stmt = 6,
+ DW_LNS_set_basic_block = 7,
+ DW_LNS_const_add_pc = 8,
+ DW_LNS_fixed_advance_pc = 9
+ };
+
+/* line number extended opcodes */
+enum dwarf_line_number_x_ops
+ {
+ DW_LNE_end_sequence = 1,
+ DW_LNE_set_address = 2,
+ DW_LNE_define_file = 3
+ };
+
+/* call frame information */
+enum dwarf_call_frame_info
+ {
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_nop = 0x00,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_def_cfa_expression = 0x0f,
+ DW_CFA_expression = 0x10,
+ /* SGI/MIPS specific */
+ DW_CFA_MIPS_advance_loc8 = 0x1d,
+
+ /* GNU extensions */
+ DW_CFA_GNU_window_save = 0x2d,
+ DW_CFA_GNU_args_size = 0x2e,
+ DW_CFA_GNU_negative_offset_extended = 0x2f
+ };
+
+#define DW_CIE_ID 0xffffffff
+#define DW_CIE_VERSION 1
+
+#define DW_CFA_extended 0
+#define DW_CFA_low_user 0x1c
+#define DW_CFA_high_user 0x3f
+
+#define DW_CHILDREN_no 0x00
+#define DW_CHILDREN_yes 0x01
+
+#define DW_ADDR_none 0
+
+/* Source language names and codes. */
+
+enum dwarf_source_language
+ {
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Mips_Assembler = 0x8001
+ };
+
+
+#define DW_LANG_lo_user 0x8000 /* implementation-defined range start */
+#define DW_LANG_hi_user 0xffff /* implementation-defined range start */
+
+/* Names and codes for macro information. */
+
+enum dwarf_macinfo_record_type
+ {
+ DW_MACINFO_define = 1,
+ DW_MACINFO_undef = 2,
+ DW_MACINFO_start_file = 3,
+ DW_MACINFO_end_file = 4,
+ DW_MACINFO_vendor_ext = 255
+ };
--- libc/sysdeps/generic/frame-dwarf2.c.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/generic/frame-dwarf2.c Wed Jul 4 21:37:34 2001
@@ -0,0 +1,732 @@
+/* Subroutines needed for unwinding DWARF 2 format stack frame info
+ for exception handling before gcc 3.0. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@cygnus.com>.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <dwarf2.h>
+#include <gccframe.h>
+
+#ifndef DWARF_FRAME_REGISTERS
+# ifdef FIRST_PSEUDO_REGISTER
+# define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
+# else
+# error DWARF_FRAME_REGISTERS is not defined.
+# endif
+#endif
+
+typedef struct frame_state
+{
+ void *cfa;
+ void *eh_ptr;
+ long cfa_offset;
+ long args_size;
+ long reg_or_offset[DWARF_FRAME_REGISTERS+1];
+ unsigned short cfa_reg;
+ unsigned short retaddr_column;
+ char saved[DWARF_FRAME_REGISTERS+1];
+ long base_offset;
+ char indirect;
+} frame_state;
+
+/* Values for 'saved' above. */
+#define REG_UNSAVED 0
+#define REG_SAVED_OFFSET 1
+#define REG_SAVED_REG 2
+
+/* Some types used by the DWARF 2 spec. */
+
+typedef int sword __attribute__ ((mode (SI)));
+typedef unsigned int uword __attribute__ ((mode (SI)));
+typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+typedef int saddr __attribute__ ((mode (pointer)));
+typedef unsigned char ubyte;
+
+/* Terminology:
+ CIE - Common Information Element
+ FDE - Frame Descriptor Element
+
+ There is one per function, and it describes where the function code
+ is located, and what the register lifetimes and stack layout are
+ within the function.
+
+ The data structures are defined in the DWARF specfication, although
+ not in a very readable way (see LITERATURE).
+
+ Every time an exception is thrown, the code needs to locate the FDE
+ for the current function, and starts to look for exception regions
+ from that FDE. This works in a two-level search:
+ a) in a linear search, find the shared image (i.e. DLL) containing
+ the PC
+ b) using the FDE table for that shared object, locate the FDE using
+ binary search (which requires the sorting). */
+
+/* The first few fields of a CIE. The CIE_id field is 0 for a CIE,
+ to distinguish it from a valid FDE. FDEs are aligned to an addressing
+ unit boundary, but the fields within are unaligned. */
+
+struct dwarf_cie {
+ uword length;
+ sword CIE_id;
+ ubyte version;
+ char augmentation[0];
+} __attribute__ ((packed, aligned (__alignof__ (void *))));
+
+/* The first few fields of an FDE. */
+
+struct dwarf_fde {
+ uword length;
+ sword CIE_delta;
+ void* pc_begin;
+ uaddr pc_range;
+} __attribute__ ((packed, aligned (__alignof__ (void *))));
+
+typedef struct dwarf_fde fde;
+
+/* The information we care about from a CIE. */
+
+struct cie_info {
+ char *augmentation;
+ void *eh_ptr;
+ int code_align;
+ int data_align;
+ unsigned ra_regno;
+};
+
+struct dwarf_eh_bases
+{
+ void *tbase;
+ void *dbase;
+ void *func;
+};
+
+extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
+
+/* The current unwind state, plus a saved copy for DW_CFA_remember_state. */
+
+struct frame_state_internal
+{
+ struct frame_state s;
+ struct frame_state_internal *saved_state;
+};
+
+/* Decode the unsigned LEB128 constant at BUF into the variable pointed to
+ by R, and return the new value of BUF. */
+
+static void *
+decode_uleb128 (unsigned char *buf, unsigned *r)
+{
+ unsigned shift = 0;
+ unsigned result = 0;
+
+ while (1)
+ {
+ unsigned byte = *buf++;
+ result |= (byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+ *r = result;
+ return buf;
+}
+
+/* Decode the signed LEB128 constant at BUF into the variable pointed to
+ by R, and return the new value of BUF. */
+
+static void *
+decode_sleb128 (unsigned char *buf, int *r)
+{
+ unsigned shift = 0;
+ unsigned result = 0;
+ unsigned byte;
+
+ while (1)
+ {
+ byte = *buf++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+ if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
+ result |= - (1 << shift);
+
+ *r = result;
+ return buf;
+}
+
+/* Read unaligned data from the instruction buffer. */
+
+union unaligned {
+ void *p;
+ unsigned b2 __attribute__ ((mode (HI)));
+ unsigned b4 __attribute__ ((mode (SI)));
+ unsigned b8 __attribute__ ((mode (DI)));
+} __attribute__ ((packed));
+static inline void *
+read_pointer (void *p)
+{ union unaligned *up = p; return up->p; }
+static inline unsigned
+read_1byte (void *p)
+{ return *(unsigned char *)p; }
+static inline unsigned
+read_2byte (void *p)
+{ union unaligned *up = p; return up->b2; }
+static inline unsigned
+read_4byte (void *p)
+{ union unaligned *up = p; return up->b4; }
+static inline unsigned long
+read_8byte (void *p)
+{ union unaligned *up = p; return up->b8; }
+
+/* Ordering function for FDEs. Functions can't overlap, so we just compare
+ their starting addresses. */
+
+static inline saddr
+fde_compare (fde *x, fde *y)
+{
+ return (saddr)x->pc_begin - (saddr)y->pc_begin;
+}
+
+/* Return the address of the FDE after P. */
+
+static inline fde *
+next_fde (fde *p)
+{
+ return (fde *)(((char *)p) + p->length + sizeof (p->length));
+}
+
+/* Sorting an array of FDEs by address.
+ (Ideally we would have the linker sort the FDEs so we don't have to do
+ it at run time. But the linkers are not yet prepared for this.) */
+
+/* This is a special mix of insertion sort and heap sort, optimized for
+ the data sets that actually occur. They look like
+ 101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130.
+ I.e. a linearly increasing sequence (coming from functions in the text
+ section), with additionally a few unordered elements (coming from functions
+ in gnu_linkonce sections) whose values are higher than the values in the
+ surrounding linear sequence (but not necessarily higher than the values
+ at the end of the linear sequence!).
+ The worst-case total run time is O(N) + O(n log (n)), where N is the
+ total number of FDEs and n is the number of erratic ones. */
+
+typedef struct fde_vector
+{
+ fde **array;
+ size_t count;
+} fde_vector;
+
+typedef struct fde_accumulator
+{
+ fde_vector linear;
+ fde_vector erratic;
+} fde_accumulator;
+
+static inline struct dwarf_cie *
+get_cie (fde *f)
+{
+ return ((void *)&f->CIE_delta) - f->CIE_delta;
+}
+
+/* Extract any interesting information from the CIE for the translation
+ unit F belongs to. */
+
+static void *
+extract_cie_info (fde *f, struct cie_info *c)
+{
+ void *p;
+ int i;
+
+ c->augmentation = get_cie (f)->augmentation;
+
+ if (strcmp (c->augmentation, "") != 0
+ && strcmp (c->augmentation, "eh") != 0
+ && c->augmentation[0] != 'z')
+ return 0;
+
+ p = c->augmentation + strlen (c->augmentation) + 1;
+
+ if (strcmp (c->augmentation, "eh") == 0)
+ {
+ c->eh_ptr = read_pointer (p);
+ p += sizeof (void *);
+ }
+ else
+ c->eh_ptr = 0;
+
+ p = decode_uleb128 (p, &c->code_align);
+ p = decode_sleb128 (p, &c->data_align);
+ c->ra_regno = *(unsigned char *)p++;
+
+ /* If the augmentation starts with 'z', we now see the length of the
+ augmentation fields. */
+ if (c->augmentation[0] == 'z')
+ {
+ p = decode_uleb128 (p, &i);
+ p += i;
+ }
+
+ return p;
+}
+
+/* Decode a DW_OP stack operation. */
+
+static void *
+decode_stack_op (unsigned char *buf, struct frame_state *state)
+{
+ enum dwarf_location_atom op;
+ int offset;
+
+ op = *buf++;
+ switch (op)
+ {
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ state->cfa_reg = op - DW_OP_reg0;
+ break;
+ case DW_OP_regx:
+ buf = decode_sleb128 (buf, &offset);
+ state->cfa_reg = offset;
+ case DW_OP_breg0:
+ case DW_OP_breg1:
+ case DW_OP_breg2:
+ case DW_OP_breg3:
+ case DW_OP_breg4:
+ case DW_OP_breg5:
+ case DW_OP_breg6:
+ case DW_OP_breg7:
+ case DW_OP_breg8:
+ case DW_OP_breg9:
+ case DW_OP_breg10:
+ case DW_OP_breg11:
+ case DW_OP_breg12:
+ case DW_OP_breg13:
+ case DW_OP_breg14:
+ case DW_OP_breg15:
+ case DW_OP_breg16:
+ case DW_OP_breg17:
+ case DW_OP_breg18:
+ case DW_OP_breg19:
+ case DW_OP_breg20:
+ case DW_OP_breg21:
+ case DW_OP_breg22:
+ case DW_OP_breg23:
+ case DW_OP_breg24:
+ case DW_OP_breg25:
+ case DW_OP_breg26:
+ case DW_OP_breg27:
+ case DW_OP_breg28:
+ case DW_OP_breg29:
+ case DW_OP_breg30:
+ case DW_OP_breg31:
+ state->cfa_reg = op - DW_OP_breg0;
+ buf = decode_sleb128 (buf, &offset);
+ state->base_offset = offset;
+ break;
+ case DW_OP_bregx:
+ buf = decode_sleb128 (buf, &offset);
+ state->cfa_reg = offset;
+ buf = decode_sleb128 (buf, &offset);
+ state->base_offset = offset;
+ break;
+ case DW_OP_deref:
+ state->indirect = 1;
+ break;
+ case DW_OP_plus_uconst:
+ buf = decode_uleb128 (buf, &offset);
+ state->cfa_offset = offset;
+ break;
+ default:
+ abort ();
+ }
+ return buf;
+}
+/* Decode one instruction's worth of DWARF 2 call frame information.
+ Used by __frame_state_for. Takes pointers P to the instruction to
+ decode, STATE to the current register unwind information, INFO to the
+ current CIE information, and PC to the current PC value. Returns a
+ pointer to the next instruction. */
+
+static void *
+execute_cfa_insn (void *p, struct frame_state_internal *state,
+ struct cie_info *info, void **pc)
+{
+ unsigned insn = *(unsigned char *)p++;
+ unsigned reg;
+ int offset;
+
+ if (insn & DW_CFA_advance_loc)
+ *pc += ((insn & 0x3f) * info->code_align);
+ else if (insn & DW_CFA_offset)
+ {
+ reg = (insn & 0x3f);
+ p = decode_uleb128 (p, &offset);
+ if (reg == state->s.cfa_reg)
+ /* Don't record anything about this register; it's only used to
+ reload SP in the epilogue. We don't want to copy in SP
+ values for outer frames; we handle restoring SP specially. */;
+ else
+ {
+ offset *= info->data_align;
+ state->s.saved[reg] = REG_SAVED_OFFSET;
+ state->s.reg_or_offset[reg] = offset;
+ }
+ }
+ else if (insn & DW_CFA_restore)
+ {
+ reg = (insn & 0x3f);
+ state->s.saved[reg] = REG_UNSAVED;
+ }
+ else switch (insn)
+ {
+ case DW_CFA_set_loc:
+ *pc = read_pointer (p);
+ p += sizeof (void *);
+ break;
+ case DW_CFA_advance_loc1:
+ *pc += read_1byte (p);
+ p += 1;
+ break;
+ case DW_CFA_advance_loc2:
+ *pc += read_2byte (p);
+ p += 2;
+ break;
+ case DW_CFA_advance_loc4:
+ *pc += read_4byte (p);
+ p += 4;
+ break;
+
+ case DW_CFA_offset_extended:
+ p = decode_uleb128 (p, ®);
+ p = decode_uleb128 (p, &offset);
+ if (reg == state->s.cfa_reg)
+ /* Don't record anything; see above. */;
+ else
+ {
+ offset *= info->data_align;
+ state->s.saved[reg] = REG_SAVED_OFFSET;
+ state->s.reg_or_offset[reg] = offset;
+ }
+ break;
+ case DW_CFA_restore_extended:
+ p = decode_uleb128 (p, ®);
+ state->s.saved[reg] = REG_UNSAVED;
+ break;
+
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_nop:
+ break;
+
+ case DW_CFA_register:
+ {
+ unsigned reg2;
+ p = decode_uleb128 (p, ®);
+ p = decode_uleb128 (p, ®2);
+ state->s.saved[reg] = REG_SAVED_REG;
+ state->s.reg_or_offset[reg] = reg2;
+ }
+ break;
+
+ case DW_CFA_def_cfa:
+ p = decode_uleb128 (p, ®);
+ p = decode_uleb128 (p, &offset);
+ state->s.cfa_reg = reg;
+ state->s.cfa_offset = offset;
+ break;
+ case DW_CFA_def_cfa_register:
+ p = decode_uleb128 (p, ®);
+ state->s.cfa_reg = reg;
+ break;
+ case DW_CFA_def_cfa_offset:
+ p = decode_uleb128 (p, &offset);
+ state->s.cfa_offset = offset;
+ break;
+ case DW_CFA_def_cfa_expression:
+ {
+ void *end;
+ state->s.cfa_reg = 0;
+ state->s.cfa_offset = 0;
+ state->s.base_offset = 0;
+ state->s.indirect = 0;
+
+ p = decode_uleb128 (p, &offset);
+ end = p + offset;
+ while (p < end)
+ p = decode_stack_op (p, &(state->s));
+ break;
+ }
+
+ case DW_CFA_remember_state:
+ {
+ struct frame_state_internal *save =
+ (struct frame_state_internal *)
+ malloc (sizeof (struct frame_state_internal));
+ memcpy (save, state, sizeof (struct frame_state_internal));
+ state->saved_state = save;
+ }
+ break;
+ case DW_CFA_restore_state:
+ {
+ struct frame_state_internal *save = state->saved_state;
+ memcpy (state, save, sizeof (struct frame_state_internal));
+ free (save);
+ }
+ break;
+
+ /* FIXME: Hardcoded for SPARC register window configuration. */
+ case DW_CFA_GNU_window_save:
+ for (reg = 16; reg < 32; ++reg)
+ {
+ state->s.saved[reg] = REG_SAVED_OFFSET;
+ state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *);
+ }
+ break;
+
+ case DW_CFA_GNU_args_size:
+ p = decode_uleb128 (p, &offset);
+ state->s.args_size = offset;
+ break;
+
+ case DW_CFA_GNU_negative_offset_extended:
+ p = decode_uleb128 (p, ®);
+ p = decode_uleb128 (p, &offset);
+ offset *= info->data_align;
+ state->s.saved[reg] = REG_SAVED_OFFSET;
+ state->s.reg_or_offset[reg] = -offset;
+ break;
+
+ default:
+ abort ();
+ }
+ return p;
+}
+
+/* Called from __throw to find the registers to restore for a given
+ PC_TARGET. The caller should allocate a local variable of `struct
+ frame_state' (declared in frame.h) and pass its address to STATE_IN. */
+
+#if defined(__linux__) && defined(__sparc__) && !defined(__arch64__)
+/* Grab some info from parent register window so that we don't
+ have to flush register windows and look it up on the stack. */
+asm (" .text \n\
+ .globl __frame_state_for \n\
+ .type __frame_state_for, #function \n\
+__frame_state_for: \n\
+ mov %fp, %o2 \n\
+ b ___frame_state_for \n\
+ mov %i0, %o3 \n\
+ ");
+
+static struct frame_state *
+___frame_state_for (void *pc_target, struct frame_state *state_in, void *pfp,
+ int i0)
+#elif defined(__linux__) && defined(__alpha__)
+struct frame_state *
+__frame_state_for (void *pc_target, struct frame_state *state_in, long a2)
+#else
+struct frame_state *
+__frame_state_for (void *pc_target, struct frame_state *state_in)
+#endif
+{
+ fde *f;
+ void *insn, *end, *pc;
+ struct cie_info info;
+ size_t s;
+ struct frame_state_internal state;
+ struct dwarf_eh_bases bases;
+
+ f = _Unwind_Find_FDE (pc_target, &bases);
+ if (f == 0)
+ return 0;
+
+ insn = extract_cie_info (f, &info);
+ if (insn == 0)
+ return 0;
+
+ memset (&state, 0, sizeof (state));
+ state.s.retaddr_column = info.ra_regno;
+ state.s.eh_ptr = info.eh_ptr;
+
+ /* First decode all the insns in the CIE. */
+ end = next_fde ((fde*) get_cie (f));
+ while (insn < end)
+ insn = execute_cfa_insn (insn, &state, &info, 0);
+
+ insn = ((fde *)f) + 1;
+
+ if (info.augmentation[0] == 'z')
+ {
+ int i;
+ insn = decode_uleb128 (insn, &i);
+ insn += i;
+ }
+
+ /* Then the insns in the FDE up to our target PC. */
+ end = next_fde (f);
+ pc = f->pc_begin;
+ while (insn < end && pc <= pc_target)
+ insn = execute_cfa_insn (insn, &state, &info, &pc);
+
+#ifdef __linux__
+ /* Binary compatibility problem: In June 2000, 2 fields
+ were added at the end of struct frame_state. If for some reason
+ __throw (or __rethrow) comes from binary/shared lib compiled
+ with egcs 1.x.y or gcc-2.95.x and __frame_state_for comes from
+ glibc compiled with gcc-2.96-RH up (gcc-3_0-branch in Apr 2001
+ works that way still), then we can overflow __throw's stack.
+ To fix this, we try to find out who calls us.
+ __frame_state_for is called by next_stack_level and __throw/__rethrow.
+ Of these, __throw/__rethrow does not care about indirect/base_offset
+ fields and next_stack_level can be found out because that's the only
+ routine which where state_in does not point into its stackframe. */
+ s = (size_t) &((struct frame_state *)0)->base_offset;
+# ifdef __i386__
+ {
+ unsigned long pbp, bp;
+ unsigned char *ppc;
+
+ asm ("movl (%%ebp), %0; movl 4(%%ebp), %1; movl %%ebp, %2"
+ : "=r" (pbp), "=r" (ppc), "=r" (bp));
+ if (pbp < (unsigned long)state_in && pbp - bp == 0x40)
+ /* We've been called from next_stack_level function.
+ All gcc-2.96-RH rpms shipped by Red Hat satisfy pbp - bp == 64,
+ none egcs 1.x.y Red Hat shipped do. */
+ {
+ unsigned char *end;
+ int indirect = 0;
+
+ /* Skim next_stack_level to see if it compares 0x74(base),0
+ and reads from 0x70(base). Stop at ret instruction. */
+ for (end = ppc + 512; ppc < end && *ppc != 0xc3 && indirect < 2;
+ ppc++)
+ {
+ if (*ppc == 0x74 && ppc[1] == 0)
+ indirect++;
+ else if (*ppc == 0x70)
+ indirect++;
+ }
+ if (indirect == 2)
+ s = sizeof (state.s);
+ }
+ }
+# elif defined(__sparc__) && !defined(__arch64__)
+ if (pfp < (unsigned long)state_in && i0 == 0)
+ /* We've been called from next_stack_level function.
+ All gcc-2.96-RH rpms shipped by Red Hat clear %i0 in next_stack_level
+ before calling __frame_state_for, all egcs 1.x.y just copy
+ %i0 into %o0, so it is guaranteed to be non-NULL. */
+ {
+ unsigned int *ppc, *end;
+ int indirect = 0;
+
+ ppc = (unsigned int) __builtin_return_address (0);
+
+ /* Skim next_stack_level to see if it does a ld?b [? + 0x218]
+ and ld?w [? + 0x214]. Stop at ret instruction. */
+ for (end = ppc + 128; ppc < end && indirect < 2
+ && (*ppc | 0x00080000) != 0x81cfe008; ppc++)
+ switch (*ppc & 0xc1b83fff)
+ {
+ case 0xc0082218: /* ld?b [? + 0x218], ? */
+ case 0xc0002214: /* ld?w [? + 0x214], ? */
+ indirect++;
+ break;
+ }
+ if (indirect == 2)
+ s = sizeof (state.s);
+ }
+# elif defined(__alpha__)
+ if ((long)state_in == a2)
+ /* We've been called most probably from next_stack_level (it has 3 arguments
+ and passes its third argument as second argument to __frame_state_for). */
+ {
+ unsigned int *ppc, *end;
+ int indirect = 0;
+
+ /* Skim next_stack_level to see if it does a ldq ?,624(?)
+ and ldl ?,632(?) resp. ldbu ?,632(?). Stop at ret instruction. */
+ for (end = ppc + 128; ppc < end && indirect < 2
+ && *ppc != 0x6bfa8001; ppc++)
+ switch (*ppc & 0xfc00ffff)
+ {
+ case 0xa4000270: /* ldq ?,624(?) */
+ case 0xa0000278: /* ldl ?,632(?) */
+ case 0xa8000278: /* ldbu ?,632(?) */
+ indirect++;
+ break;
+ }
+ if (indirect == 2)
+ s = sizeof (state.s);
+ }
+# else
+ s = sizeof (state.s);
+# endif
+#else
+ s = sizeof (state.s);
+#endif
+ if (state.s.indirect && s < sizeof (state.s))
+ abort ();
+ memcpy (state_in, &state.s, s);
+ return state_in;
+}
--- libc/sysdeps/generic/gccframe.h.gcc Thu Sep 28 16:07:25 2000
+++ libc/sysdeps/generic/gccframe.h Wed Jul 4 21:37:34 2001
@@ -1,5 +1,5 @@
/* Definition of object in frame unwind info. Generic version.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,14 +17,16 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* This must match what's in frame.h in gcc. */
+#include <sys/types.h>
-struct object
+struct dwarf_fde;
+
+struct object
{
void *pc_begin;
void *pc_end;
- void *fde_begin;
- void *fde_array;
- __SIZE_TYPE__ count;
+ struct dwarf_fde *fde_begin;
+ struct dwarf_fde **fde_array;
+ size_t count;
struct object *next;
};
--- libc/sysdeps/i386/gccframe.h.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/i386/gccframe.h Wed Jul 4 21:37:34 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define DWARF_FRAME_REGISTERS 17
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/m68k/gccframe.h.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/m68k/gccframe.h Wed Jul 4 21:37:34 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define FIRST_PSEUDO_REGISTER 24
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/mips/gccframe.h.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/mips/gccframe.h Wed Jul 4 21:37:34 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define FIRST_PSEUDO_REGISTER 76
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/powerpc/gccframe.h.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/powerpc/gccframe.h Wed Jul 4 21:37:34 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define DWARF_FRAME_REGISTERS 77
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/s390/s390-32/gccframe.h.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/s390/s390-32/gccframe.h Wed Jul 4 21:37:34 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define FIRST_PSEUDO_REGISTER 20
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/sparc/gccframe.h.gcc Wed Jul 4 21:37:34 2001
+++ libc/sysdeps/sparc/gccframe.h Wed Jul 4 21:37:34 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define FIRST_PSEUDO_REGISTER 101
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/unix/sysv/linux/Versions.gcc Thu Nov 23 01:04:30 2000
+++ libc/sysdeps/unix/sysv/linux/Versions Thu Jul 5 08:58:25 2001
@@ -94,4 +94,14 @@ libc {
# p*
pivot_root;
}
+%ifdef HAVE_DWARF2_UNWIND_GCC_3
+ GCC_3.0 {
+ # Exception handling support functions from libgcc in gcc 3.0
+ __register_frame_info_bases; __deregister_frame_info_bases;
+ __register_frame_info_table_bases;
+%ifdef HAVE_UNWIND_FIND_FDE
+ _Unwind_Find_FDE;
+%endif
+ }
+%endif
}
--- libc/sysdeps/unix/sysv/linux/alpha/Makefile.gcc Mon Mar 20 12:23:05 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/Makefile Wed Jul 4 23:09:15 2001
@@ -23,3 +23,13 @@ ifeq ($(subdir),signal)
sysdep_routines += rt_sigsuspend rt_sigprocmask rt_sigtimedwait \
rt_sigqueueinfo rt_sigaction rt_sigpending
endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/arm/Makefile.gcc Fri Mar 9 22:36:31 2001
+++ libc/sysdeps/unix/sysv/linux/arm/Makefile Wed Jul 4 23:10:09 2001
@@ -19,4 +19,12 @@ sysdep-dl-routines += dl-procinfo
sysdep_routines += dl-procinfo
# extra shared linker files to link only into dl-allobjs.so
sysdep-rtld-routines += dl-procinfo
+
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
endif
--- libc/sysdeps/unix/sysv/linux/i386/Makefile.gcc Wed May 23 17:29:06 2001
+++ libc/sysdeps/unix/sysv/linux/i386/Makefile Wed Jul 4 21:37:34 2001
@@ -12,6 +12,14 @@ sysdep-dl-routines += dl-procinfo
sysdep_routines += dl-procinfo
# extra shared linker files to link only into dl-allobjs.so
sysdep-rtld-routines += dl-procinfo
+
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
endif
ifeq ($(subdir),resource)
--- libc/sysdeps/unix/sysv/linux/m68k/Makefile.gcc Sat Oct 14 10:48:34 2000
+++ libc/sysdeps/unix/sysv/linux/m68k/Makefile Wed Jul 4 23:10:40 2001
@@ -10,6 +10,14 @@ endif
ifeq ($(subdir),elf)
sysdep-others += lddlibc4
install-bin += lddlibc4
+
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
endif
ifeq ($(subdir),resource)
--- libc/sysdeps/unix/sysv/linux/mips/Makefile.gcc Fri May 4 20:54:13 2001
+++ libc/sysdeps/unix/sysv/linux/mips/Makefile Wed Jul 4 23:11:03 2001
@@ -9,3 +9,13 @@ sysdep_routines += cachectl cacheflush s
sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h
endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/powerpc/Makefile.gcc Wed May 23 17:29:06 2001
+++ libc/sysdeps/unix/sysv/linux/powerpc/Makefile Wed Jul 4 23:11:25 2001
@@ -6,3 +6,13 @@ endif
ifeq ($(subdir),resource)
sysdep_routines += oldgetrlimit64
endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile.gcc Wed May 23 17:29:06 2001
+++ libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile Wed Jul 4 23:12:00 2001
@@ -6,3 +6,13 @@ endif
ifeq ($(subdir),resource)
sysdep_routines += oldgetrlimit64
endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/sparc/Makefile.gcc Wed Nov 15 17:48:14 2000
+++ libc/sysdeps/unix/sysv/linux/sparc/Makefile Wed Jul 4 23:12:36 2001
@@ -42,3 +42,13 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%.
mv -f $(@:.h=.d)-t2 $(@:.h=.d)
endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+ifeq (yes,$(need-frame-dwarf2))
+# It is needed for gcc 3.0.
+sysdep_routines += frame-dwarf2
+shared-only-routines += frame-dwarf2
+endif
+endif
+endif
More information about the Libc-alpha
mailing list