This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Next attempt on the gcc3 vs glibc2.2.4 patch


On Sun, Aug 05, 2001 at 06:00:14AM -0700, Ulrich Drepper wrote:
> Andreas Jaeger <aj@suse.de> writes:
> 
> > Shouldn't we add patch for configure to check for GCC 3.0 and remove
> > it as soon as the patches go in?
> 
> I'll do this for the final release if this is still the case (and I
> assume it will be).

Here is an updated version of the GCC 3.0 vs. GLIBC 2.2.4 patch.
Unlike the previous one, it does not care which gcc was used to build GLIBC
- everywhere but on Linux/IA-64 it exports the new GCC 3.0 unwind
register/deregister routines plus _Unwind_Find_FDE (using gcc's
unwind-dw2-fde.c with just a few changes for glibc), plus on platforms which
used to export __frame_state_for from glibc it does so. __frame_state_for
implementation in GLIBC means first try to dlopen libgcc_s.so.1 if it exists
and call __frame_state_for in there, if it does not exist, it has a
fallback, so that GLIBC 2.2.4 does not require GCC 3.0.1+'s libgcc to be
installed.
I've tested it using various tests I described last time (basically all
gcc version combinations of C++ main program and -fexception C shared
library the C++ main program throws exceptions through), with both glibc
compiled with GCC 2.96-RH and GCC 3.0.1 CVS.

2001-08-06  Jakub Jelinek  <jakub@redhat.com>
	    H.J. Lu  <hjl@gnu.org>

	* Versions.def (libc): Add GCC_3.0.
	* configure.in (libc_cv_gcc_static_libgcc): Set to -static-libgcc
	if gcc supports this flag.
	(EXPORT_UNWIND_FIND_FDE): Define unless target configure
	disables it.
	* configure: Rebuilt.
	* config.h.in (EXPORT_UNWIND_FIND_FDE): Add.
	* config.make.in (static-libgcc): Add.
	* Makerules (build-shlib-helper, build-module-helper): Use it.
	* elf/soinit.c (__libc_global_ctors): Set tbases and dbases i
	necessary.
	* elf/Versions (__register_frame_info, __deregister_frame_info): Add
	at GLIBC_2.0.
	(__register_frame_info_bases, __register_frame_info_table_bases,
	__deregister_frame_info_bases, _Unwind_Find_FDE): Add at GCC_3.0.
	* elf/Makefile (routines): Add unwind-dw2-fde.
	(shared-only-routines): Add unwind-dw2-fde.
	* sysdeps/alpha/gccframe.h: New.
	* sysdeps/arm/gccframe.h: New.
	* sysdeps/generic/dwarf2.h: New.
	* sysdeps/generic/gccframe.h (struct object): Update from gcc 3.0.
	* sysdeps/generic/unwind-dw2-fde.c: New.
	* sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c: New.
	* sysdeps/generic/unwind-dw2-fde.h: New.
	* sysdeps/generic/unwind-dw2.c: New.
	* sysdeps/generic/unwind-pe.h: New.
	* sysdeps/generic/unwind.h: New.
	* sysdeps/hppa/gccframe.h: New.
	* sysdeps/i386/gccframe.h: New.
	* sysdeps/m68k/gccframe.h: New.
	* sysdeps/mips/gccframe.h: New.
	* sysdeps/powerpc/gccframe.h: New.
	* sysdeps/s390/gccframe.h: New.
	* sysdeps/sh/gccframe.h: New.
	* sysdeps/sparc/gccframe.h: New.
	* sysdeps/vax/gccframe.h: New.
	* sysdeps/unix/sysv/linux/configure.in (libc_cv_gcc_unwind_find_fde):
	Set to no on ia64.
	* sysdeps/unix/sysv/linux/configure: Rebuilt.
	* sysdeps/mach/hurd/i386/Versions (__register_frame_info,
	__deregister_frame_info): Move to elf/Versions.
	* sysdeps/unix/sysv/linux/m68k/Versions: Likewise.
	* sysdeps/unix/sysv/linux/arm/Versions: Likewise.
	* sysdeps/unix/sysv/linux/alpha/Versions: Likewise.
	* sysdeps/unix/sysv/linux/i386/Versions: Likewise.
	* sysdeps/unix/sysv/linux/mips/Versions: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/Versions: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/Versions: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/Versions: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/Versions: Likewise.
	* sysdeps/mach/hurd/i386/Makefile (sysdep-routines): Add
	framestate.
	* sysdeps/unix/sysv/linux/arm/Makefile: Likewise.
	* sysdeps/unix/sysv/linux/alpha/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/elf/soinit.c.jj	Fri Feb  2 06:16:35 2001
+++ libc/elf/soinit.c	Mon Aug  6 04:47:19 2001
@@ -48,6 +48,22 @@ __libc_global_ctors (void)
   {
     static struct object ob;
     __register_frame_info (__EH_FRAME_BEGIN__, &ob);
+#  if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
+    /* This is problematic.
+       We cannot use __register_frame_info_bases here, since if
+       e.g. libstdc++ from gcc < 3.0 comes earlier in the search
+       scope than glibc, we need to register with it.  */
+    if (ob.pc_begin == (void *)-1
+	&& (char *) ob.u.single == __EH_FRAME_BEGIN__)
+      {
+#   ifdef CRT_GET_RFIB_TEXT
+	CRT_GET_RFIB_TEXT (ob.tbase);
+#   endif
+#   ifdef CRT_GET_RFIB_DATA
+	CRT_GET_RFIB_DATA (ob.dbase);
+#   endif
+      }
+#  endif
   }
 # else
   __register_frame (__EH_FRAME_BEGIN__);
--- libc/elf/Versions.jj	Sat Aug  4 15:00:20 2001
+++ libc/elf/Versions	Mon Aug  6 05:22:38 2001
@@ -2,6 +2,9 @@ libc {
   GLIBC_2.0 {
     # functions used in other libraries
     _dl_open; _dl_close; _dl_addr;
+%ifdef EXPORT_UNWIND_FIND_FDE
+    __register_frame_info; __deregister_frame_info;
+%endif
   }
   GLIBC_2.1 {
     # functions used in other libraries
@@ -17,6 +20,12 @@ libc {
   GLIBC_2.2.4 {
     dl_iterate_phdr;
   }
+%ifdef EXPORT_UNWIND_FIND_FDE
+  GCC_3.0 {
+    __register_frame_info_bases; __deregister_frame_info_bases;
+    __register_frame_info_table_bases; _Unwind_Find_FDE;
+  }
+%endif
 }
 
 ld {
--- libc/elf/Makefile.jj	Wed Jul 25 17:30:16 2001
+++ libc/elf/Makefile	Mon Aug  6 05:24:14 2001
@@ -23,7 +23,8 @@ subdir		:= elf
 headers		= elf.h bits/elfclass.h link.h
 routines	= $(dl-routines) dl-open dl-close dl-support dl-iteratephdr \
 		  dl-iteratephdr-static dl-addr enbl-secure dl-profstub \
-		  dl-origin dl-libc dl-sym
+		  dl-origin dl-libc dl-sym unwind-dw2-fde
+shared-only-routines = unwind-dw2-fde
 
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
--- libc/sysdeps/alpha/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/alpha/gccframe.h	Sat Aug  4 16:04:16 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  alpha 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/arm/gccframe.h	Sat Aug  4 16:04:24 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  arm 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/generic/dwarf2.h	Fri Jun  8 09:40:54 2001
@@ -0,0 +1,585 @@
+/* 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++ */
+    DW_TAG_GNU_BINCL = 0x4104,
+    DW_TAG_GNU_EINCL = 0x4105
+  };
+
+#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,
+    /* Dwarf 2.1 */
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf = 0x12,
+    DW_CFA_def_cfa_offset_sf = 0x13,
+
+    /* 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_Java = 0x000b,
+    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
+  };
+
+
+/* @@@ For use with GNU frame unwind information.  */
+
+#define DW_EH_PE_absptr		0x00
+#define DW_EH_PE_omit		0xff
+
+#define DW_EH_PE_uleb128	0x01
+#define DW_EH_PE_udata2		0x02
+#define DW_EH_PE_udata4		0x03
+#define DW_EH_PE_udata8		0x04
+#define DW_EH_PE_sleb128	0x09
+#define DW_EH_PE_sdata2		0x0A
+#define DW_EH_PE_sdata4		0x0B
+#define DW_EH_PE_sdata8		0x0C
+#define DW_EH_PE_signed		0x08
+
+#define DW_EH_PE_pcrel		0x10
+#define DW_EH_PE_textrel	0x20
+#define DW_EH_PE_datarel	0x30
+#define DW_EH_PE_funcrel	0x40
+#define DW_EH_PE_aligned	0x50
+
+#define DW_EH_PE_indirect	0x80
--- libc/sysdeps/generic/gccframe.h.jj	Mon Jul  9 14:57:58 2001
+++ libc/sysdeps/generic/gccframe.h	Sat Aug  4 15:40:57 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,34 @@
    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 dwarf_fde;
+struct fde_vector;
 
 struct object
 {
   void *pc_begin;
-  void *pc_end;
-  void *fde_begin;
-  void *fde_array;
-  __SIZE_TYPE__ count;
+  void *tbase;
+  void *dbase;
+  union {
+    struct dwarf_fde *single;
+    struct dwarf_fde **array;
+    struct fde_vector *sort;
+  } u;
+
+  union {
+    struct {
+      unsigned long sorted : 1;
+      unsigned long from_array : 1;
+      unsigned long mixed_encoding : 1;
+      unsigned long encoding : 8;
+      /* ??? Wish there was an easy way to detect a 64-bit host here;
+	 we've got 32 bits left to play with... */
+      unsigned long count : 21;
+    } b;
+    size_t i;
+  } s;
+
   struct object *next;
 };
--- libc/sysdeps/generic/unwind-dw2-fde.c.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/generic/unwind-dw2-fde.c	Mon Aug  6 03:49:55 2001
@@ -0,0 +1,1013 @@
+/* Subroutines needed for unwinding stack frames for exception handling.  */
+/* 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.  */
+
+#ifdef _LIBC
+#include <stdlib.h>
+#include <string.h>
+#include <bits/libc-lock.h>
+#include <dwarf2.h>
+#include <unwind.h>
+#define NO_BASE_OF_ENCODED_VALUE
+#include <unwind-pe.h>
+#include <unwind-dw2-fde.h>
+#else
+#include "tconfig.h"
+#include "tsystem.h"
+#include "dwarf2.h"
+#include "unwind.h"
+#define NO_BASE_OF_ENCODED_VALUE
+#include "unwind-pe.h"
+#include "unwind-dw2-fde.h"
+#include "gthr.h"
+#endif
+
+/* The unseen_objects list contains objects that have been registered
+   but not yet categorized in any way.  The seen_objects list has had
+   it's pc_begin and count fields initialized at minimum, and is sorted
+   by decreasing value of pc_begin.  */
+static struct object *unseen_objects;
+static struct object *seen_objects;
+
+#ifdef _LIBC
+
+__libc_lock_define_initialized_recursive (static, object_mutex)
+#define init_object_mutex_once()
+#define __gthread_mutex_lock(m) __libc_lock_lock (*(m))
+#define __gthread_mutex_unlock(m) __libc_lock_unlock (*(m))
+
+#else
+
+#ifdef __GTHREAD_MUTEX_INIT
+static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
+#else
+static __gthread_mutex_t object_mutex;
+#endif
+
+#ifdef __GTHREAD_MUTEX_INIT_FUNCTION
+static void 
+init_object_mutex (void)
+{
+  __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
+}
+
+static void
+init_object_mutex_once (void)
+{
+  static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+  __gthread_once (&once, init_object_mutex);
+}
+#else
+#define init_object_mutex_once()
+#endif
+
+#endif /* _LIBC */
+
+/* Called from crtbegin.o to register the unwind info for an object.  */
+
+void
+__register_frame_info_bases (void *begin, struct object *ob,
+			     void *tbase, void *dbase)
+{
+  ob->pc_begin = (void *)-1;
+  ob->tbase = tbase;
+  ob->dbase = dbase;
+  ob->u.single = begin;
+  ob->s.i = 0;
+  ob->s.b.encoding = DW_EH_PE_omit;
+
+  init_object_mutex_once ();
+  __gthread_mutex_lock (&object_mutex);
+
+  ob->next = unseen_objects;
+  unseen_objects = ob;
+
+  __gthread_mutex_unlock (&object_mutex);
+}
+
+void
+__register_frame_info (void *begin, struct object *ob)
+{
+  __register_frame_info_bases (begin, ob, 0, 0);
+}
+
+void
+__register_frame (void *begin)
+{
+  struct object *ob = (struct object *) malloc (sizeof (struct object));
+  __register_frame_info (begin, ob);                       
+}
+
+/* Similar, but BEGIN is actually a pointer to a table of unwind entries
+   for different translation units.  Called from the file generated by
+   collect2.  */
+
+void
+__register_frame_info_table_bases (void *begin, struct object *ob,
+				   void *tbase, void *dbase)
+{
+  ob->pc_begin = (void *)-1;
+  ob->tbase = tbase;
+  ob->dbase = dbase;
+  ob->u.array = begin;
+  ob->s.i = 0;
+  ob->s.b.from_array = 1;
+  ob->s.b.encoding = DW_EH_PE_omit;
+
+  init_object_mutex_once ();
+  __gthread_mutex_lock (&object_mutex);
+
+  ob->next = unseen_objects;
+  unseen_objects = ob;
+
+  __gthread_mutex_unlock (&object_mutex);
+}
+
+void
+__register_frame_info_table (void *begin, struct object *ob)
+{
+  __register_frame_info_table_bases (begin, ob, 0, 0);
+}
+
+void
+__register_frame_table (void *begin)
+{
+  struct object *ob = (struct object *) malloc (sizeof (struct object));
+  __register_frame_info_table (begin, ob);
+}
+
+/* Called from crtbegin.o to deregister the unwind info for an object.  */
+/* ??? Glibc has for a while now exported __register_frame_info and
+   __deregister_frame_info.  If we call __register_frame_info_bases
+   from crtbegin (wherein it is declared weak), and this object does
+   not get pulled from libgcc.a for other reasons, then the
+   invocation of __deregister_frame_info will be resolved from glibc.
+   Since the registration did not happen there, we'll abort.
+
+   Therefore, declare a new deregistration entry point that does the
+   exact same thing, but will resolve to the same library as 
+   implements __register_frame_info_bases.  */
+
+void *
+__deregister_frame_info_bases (void *begin)
+{
+  struct object **p;
+  struct object *ob = 0;
+
+  init_object_mutex_once ();
+  __gthread_mutex_lock (&object_mutex);
+
+  for (p = &unseen_objects; *p ; p = &(*p)->next)
+    if ((*p)->u.single == begin)
+      {
+	ob = *p;
+	*p = ob->next;
+	goto out;
+      }
+
+  for (p = &seen_objects; *p ; p = &(*p)->next)
+    if ((*p)->s.b.sorted)
+      {
+	if ((*p)->u.sort->orig_data == begin)
+	  {
+	    ob = *p;
+	    *p = ob->next;
+	    free (ob->u.sort);
+	    goto out;
+	  }
+      }
+    else
+      {
+	if ((*p)->u.single == begin)
+	  {
+	    ob = *p;
+	    *p = ob->next;
+	    goto out;
+	  }
+      }
+
+  __gthread_mutex_unlock (&object_mutex);
+  abort ();
+
+ out:
+  __gthread_mutex_unlock (&object_mutex);
+  return (void *) ob;
+}
+
+void *
+__deregister_frame_info (void *begin)
+{
+  return __deregister_frame_info_bases (begin);
+}
+
+void
+__deregister_frame (void *begin)
+{
+  free (__deregister_frame_info (begin));
+}
+
+
+/* Like base_of_encoded_value, but take the base from a struct object
+   instead of an _Unwind_Context.  */
+
+static _Unwind_Ptr
+base_from_object (unsigned char encoding, struct object *ob)
+{
+  if (encoding == DW_EH_PE_omit)
+    return 0;
+
+  switch (encoding & 0x70)
+    {
+    case DW_EH_PE_absptr:
+    case DW_EH_PE_pcrel:
+    case DW_EH_PE_aligned:
+      return 0;
+
+    case DW_EH_PE_textrel:
+      return (_Unwind_Ptr) ob->tbase;
+    case DW_EH_PE_datarel:
+      return (_Unwind_Ptr) ob->dbase;
+    }
+  abort ();
+}
+
+/* Return the FDE pointer encoding from the CIE.  */
+/* ??? This is a subset of extract_cie_info from unwind-dw2.c.  */
+
+static int
+get_cie_encoding (struct dwarf_cie *cie)
+{
+  const unsigned char *aug, *p;
+  _Unwind_Ptr dummy;
+
+  aug = cie->augmentation;
+  if (aug[0] != 'z')
+    return DW_EH_PE_absptr;
+
+  p = aug + strlen (aug) + 1;		/* Skip the augmentation string.  */
+  p = read_uleb128 (p, &dummy);		/* Skip code alignment.  */
+  p = read_sleb128 (p, &dummy);		/* Skip data alignment.  */
+  p++;					/* Skip return address column.  */
+
+  aug++;				/* Skip 'z' */
+  p = read_uleb128 (p, &dummy);		/* Skip augmentation length.  */
+  while (1)
+    {
+      /* This is what we're looking for.  */
+      if (*aug == 'R')
+	return *p;
+      /* Personality encoding and pointer.  */
+      else if (*aug == 'P')
+	{
+	  /* ??? Avoid dereferencing indirect pointers, since we're
+	     faking the base address.  Gotta keep DW_EH_PE_aligned
+	     intact, however.  */
+	  p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
+	}
+      /* LSDA encoding.  */
+      else if (*aug == 'L')
+	p++;
+      /* Otherwise end of string, or unknown augmentation.  */
+      else
+	return DW_EH_PE_absptr;
+      aug++;
+    }
+}
+
+static inline int
+get_fde_encoding (struct dwarf_fde *f)
+{
+  return get_cie_encoding (get_cie (f));
+}
+
+
+/* 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.)  */
+
+/* Comparison routines.  Three variants of increasing complexity.  */
+
+static saddr
+fde_unencoded_compare (struct object *ob __attribute__((unused)),
+		       fde *x, fde *y)
+{
+  return *(saddr *)x->pc_begin - *(saddr *)y->pc_begin;
+}
+
+static saddr
+fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
+{
+  _Unwind_Ptr base, x_ptr, y_ptr;
+
+  base = base_from_object (ob->s.b.encoding, ob);
+  read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
+  read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
+
+  return x_ptr - y_ptr;
+}
+
+static saddr
+fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
+{
+  int x_encoding, y_encoding;
+  _Unwind_Ptr x_ptr, y_ptr;
+
+  x_encoding = get_fde_encoding (x);
+  read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
+				x->pc_begin, &x_ptr);
+
+  y_encoding = get_fde_encoding (y);
+  read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
+				y->pc_begin, &y_ptr);
+
+  return x_ptr - y_ptr;
+}
+
+typedef saddr (*fde_compare_t) (struct object *, fde *, fde *);
+
+
+/* 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.  */
+
+struct fde_accumulator
+{
+  struct fde_vector *linear;
+  struct fde_vector *erratic;
+};
+
+static inline int
+start_fde_sort (struct fde_accumulator *accu, size_t count)
+{
+  size_t size;
+  if (! count)
+    return 0;
+
+  size = sizeof (struct fde_vector) + sizeof (fde *) * count;
+  if ((accu->linear = (struct fde_vector *) malloc (size)))
+    {
+      accu->linear->count = 0;
+      if ((accu->erratic = (struct fde_vector *) malloc (size)))
+	accu->erratic->count = 0;
+      return 1;
+    }
+  else
+    return 0;  
+}
+
+static inline void
+fde_insert (struct fde_accumulator *accu, fde *this_fde)
+{
+  if (accu->linear)
+    accu->linear->array[accu->linear->count++] = this_fde;
+}
+
+/* Split LINEAR into a linear sequence with low values and an erratic
+   sequence with high values, put the linear one (of longest possible
+   length) into LINEAR and the erratic one into ERRATIC. This is O(N).
+   
+   Because the longest linear sequence we are trying to locate within the
+   incoming LINEAR array can be interspersed with (high valued) erratic
+   entries.  We construct a chain indicating the sequenced entries.
+   To avoid having to allocate this chain, we overlay it onto the space of
+   the ERRATIC array during construction.  A final pass iterates over the
+   chain to determine what should be placed in the ERRATIC array, and
+   what is the linear sequence.  This overlay is safe from aliasing.  */
+
+static inline void
+fde_split (struct object *ob, fde_compare_t fde_compare,
+	   struct fde_vector *linear, struct fde_vector *erratic)
+{
+  static fde *marker;
+  size_t count = linear->count;
+  fde **chain_end = &marker;
+  size_t i, j, k;
+
+  /* This should optimize out, but it is wise to make sure this assumption
+     is correct. Should these have different sizes, we cannot cast between
+     them and the overlaying onto ERRATIC will not work.  */
+  if (sizeof (fde *) != sizeof (fde **))
+    abort ();
+  
+  for (i = 0; i < count; i++)
+    {
+      fde **probe;
+      
+      for (probe = chain_end;
+           probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
+           probe = chain_end)
+        {
+          chain_end = (fde **)erratic->array[probe - linear->array];
+          erratic->array[probe - linear->array] = NULL;
+        }
+      erratic->array[i] = (fde *)chain_end;
+      chain_end = &linear->array[i];
+    }
+
+  /* Each entry in LINEAR which is part of the linear sequence we have
+     discovered will correspond to a non-NULL entry in the chain we built in
+     the ERRATIC array.  */
+  for (i = j = k = 0; i < count; i++)
+    if (erratic->array[i])
+      linear->array[j++] = linear->array[i];
+    else
+      erratic->array[k++] = linear->array[i];
+  linear->count = j;
+  erratic->count = k;
+}
+
+/* This is O(n log(n)).  BSD/OS defines heapsort in stdlib.h, so we must
+   use a name that does not conflict.  */
+
+static void
+frame_heapsort (struct object *ob, fde_compare_t fde_compare,
+		struct fde_vector *erratic)
+{
+  /* For a description of this algorithm, see:
+     Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
+     p. 60-61. */
+  fde ** a = erratic->array;
+  /* A portion of the array is called a "heap" if for all i>=0:
+     If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
+     If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
+#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
+  size_t n = erratic->count;
+  size_t m = n;
+  size_t i;
+
+  while (m > 0)
+    {
+      /* Invariant: a[m..n-1] is a heap. */
+      m--;
+      for (i = m; 2*i+1 < n; )
+        {
+          if (2*i+2 < n
+              && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
+              && fde_compare (ob, a[2*i+2], a[i]) > 0)
+            {
+              SWAP (a[i], a[2*i+2]);
+              i = 2*i+2;
+            }
+          else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
+            {
+              SWAP (a[i], a[2*i+1]);
+              i = 2*i+1;
+            }
+          else
+            break;
+        }
+    }
+  while (n > 1)
+    {
+      /* Invariant: a[0..n-1] is a heap. */
+      n--;
+      SWAP (a[0], a[n]);
+      for (i = 0; 2*i+1 < n; )
+        {
+          if (2*i+2 < n
+              && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
+              && fde_compare (ob, a[2*i+2], a[i]) > 0)
+            {
+              SWAP (a[i], a[2*i+2]);
+              i = 2*i+2;
+            }
+          else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
+            {
+              SWAP (a[i], a[2*i+1]);
+              i = 2*i+1;
+            }
+          else
+            break;
+        }
+    }
+#undef SWAP
+}
+
+/* Merge V1 and V2, both sorted, and put the result into V1. */
+static inline void
+fde_merge (struct object *ob, fde_compare_t fde_compare,
+	   struct fde_vector *v1, struct fde_vector *v2)
+{
+  size_t i1, i2;
+  fde * fde2;
+
+  i2 = v2->count;
+  if (i2 > 0)
+    {
+      i1 = v1->count;
+      do {
+        i2--;
+        fde2 = v2->array[i2];
+        while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
+          {
+            v1->array[i1+i2] = v1->array[i1-1];
+            i1--;
+          }
+        v1->array[i1+i2] = fde2;
+      } while (i2 > 0);
+      v1->count += v2->count;
+    }
+}
+
+static inline void
+end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
+{
+  fde_compare_t fde_compare;
+
+  if (accu->linear && accu->linear->count != count)
+    abort ();
+
+  if (ob->s.b.mixed_encoding)
+    fde_compare = fde_mixed_encoding_compare;
+  else if (ob->s.b.encoding == DW_EH_PE_absptr)
+    fde_compare = fde_unencoded_compare;
+  else
+    fde_compare = fde_single_encoding_compare;
+
+  if (accu->erratic)
+    {
+      fde_split (ob, fde_compare, accu->linear, accu->erratic);
+      if (accu->linear->count + accu->erratic->count != count)
+	abort ();
+      frame_heapsort (ob, fde_compare, accu->erratic);
+      fde_merge (ob, fde_compare, accu->linear, accu->erratic);
+      free (accu->erratic);
+    }
+  else
+    {
+      /* We've not managed to malloc an erratic array,
+	 so heap sort in the linear one.  */
+      frame_heapsort (ob, fde_compare, accu->linear);
+    }
+}
+
+
+/* Update encoding, mixed_encoding, and pc_begin for OB for the 
+   fde array beginning at THIS_FDE.  Return the number of fdes
+   encountered along the way.  */
+
+static size_t
+classify_object_over_fdes (struct object *ob, fde *this_fde)
+{
+  struct dwarf_cie *last_cie = 0;
+  size_t count = 0;
+  int encoding = DW_EH_PE_absptr;
+  _Unwind_Ptr base = 0;
+
+  for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+    {
+      struct dwarf_cie *this_cie;
+      _Unwind_Ptr mask, pc_begin;
+
+      /* Skip CIEs.  */
+      if (this_fde->CIE_delta == 0)
+	continue;
+
+      /* Determine the encoding for this FDE.  Note mixed encoded
+	 objects for later.  */
+      this_cie = get_cie (this_fde);
+      if (this_cie != last_cie)
+	{
+	  last_cie = this_cie;
+	  encoding = get_cie_encoding (this_cie);
+	  base = base_from_object (encoding, ob);
+	  if (ob->s.b.encoding == DW_EH_PE_omit)
+	    ob->s.b.encoding = encoding;
+	  else if (ob->s.b.encoding != encoding)
+	    ob->s.b.mixed_encoding = 1;
+	}
+
+      read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
+				    &pc_begin);
+
+      /* Take care to ignore link-once functions that were removed.
+	 In these cases, the function address will be NULL, but if
+	 the encoding is smaller than a pointer a true NULL may not
+	 be representable.  Assume 0 in the representable bits is NULL.  */
+      mask = size_of_encoded_value (encoding);
+      if (mask < sizeof (void *))
+	mask = (1L << (mask << 3)) - 1;
+      else
+	mask = -1;
+
+      if ((pc_begin & mask) == 0)
+	continue;
+
+      count += 1;
+      if ((void *)pc_begin < ob->pc_begin)
+	ob->pc_begin = (void *)pc_begin;
+    }
+
+  return count;
+}
+
+static void
+add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
+{
+  struct dwarf_cie *last_cie = 0;
+  int encoding = ob->s.b.encoding;
+  _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
+
+  for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+    {
+      struct dwarf_cie *this_cie;
+
+      /* Skip CIEs.  */
+      if (this_fde->CIE_delta == 0)
+	continue;
+
+      if (ob->s.b.mixed_encoding)
+	{
+	  /* Determine the encoding for this FDE.  Note mixed encoded
+	     objects for later.  */
+	  this_cie = get_cie (this_fde);
+	  if (this_cie != last_cie)
+	    {
+	      last_cie = this_cie;
+	      encoding = get_cie_encoding (this_cie);
+	      base = base_from_object (encoding, ob);
+	    }
+	}
+
+      if (encoding == DW_EH_PE_absptr)
+	{
+	  if (*(_Unwind_Ptr *)this_fde->pc_begin == 0)
+	    continue;
+	}
+      else
+	{
+	  _Unwind_Ptr pc_begin, mask;
+
+	  read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
+					&pc_begin);
+
+	  /* Take care to ignore link-once functions that were removed.
+	     In these cases, the function address will be NULL, but if
+	     the encoding is smaller than a pointer a true NULL may not
+	     be representable.  Assume 0 in the representable bits is NULL.  */
+	  mask = size_of_encoded_value (encoding);
+	  if (mask < sizeof (void *))
+	    mask = (1L << (mask << 3)) - 1;
+	  else
+	    mask = -1;
+
+	  if ((pc_begin & mask) == 0)
+	    continue;
+	}
+
+      fde_insert (accu, this_fde);
+    }
+}
+
+/* Set up a sorted array of pointers to FDEs for a loaded object.  We
+   count up the entries before allocating the array because it's likely to
+   be faster.  We can be called multiple times, should we have failed to
+   allocate a sorted fde array on a previous occasion.  */
+
+static inline void
+init_object (struct object* ob)
+{
+  struct fde_accumulator accu;
+  size_t count;
+
+  count = ob->s.b.count;
+  if (count == 0)
+    {
+      if (ob->s.b.from_array)
+	{
+	  fde **p = ob->u.array;
+	  for (count = 0; *p; ++p)
+	    count += classify_object_over_fdes (ob, *p);
+	}
+      else
+	count = classify_object_over_fdes (ob, ob->u.single);
+
+      /* The count field we have in the main struct object is somewhat
+	 limited, but should suffice for virtually all cases.  If the
+	 counted value doesn't fit, re-write a zero.  The worst that
+	 happens is that we re-count next time -- admittedly non-trivial
+	 in that this implies some 2M fdes, but at least we function.  */
+      ob->s.b.count = count;
+      if (ob->s.b.count != count)
+	ob->s.b.count = 0;
+    }
+
+  if (!start_fde_sort (&accu, count))
+    return;
+
+  if (ob->s.b.from_array)
+    {
+      fde **p;
+      for (p = ob->u.array; *p; ++p)
+        add_fdes (ob, &accu, *p);
+    }
+  else
+    add_fdes (ob, &accu, ob->u.single);
+
+  end_fde_sort (ob, &accu, count);
+
+  /* Save the original fde pointer, since this is the key by which the
+     DSO will deregister the object.  */
+  accu.linear->orig_data = ob->u.single;
+  ob->u.sort = accu.linear;
+
+  ob->s.b.sorted = 1;
+}
+
+/* A linear search through a set of FDEs for the given PC.  This is
+   used when there was insufficient memory to allocate and sort an
+   array.  */
+
+static fde *
+linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
+{
+  struct dwarf_cie *last_cie = 0;
+  int encoding = ob->s.b.encoding;
+  _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
+
+  for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+    {
+      struct dwarf_cie *this_cie;
+      _Unwind_Ptr pc_begin, pc_range;
+
+      /* Skip CIEs.  */
+      if (this_fde->CIE_delta == 0)
+	continue;
+
+      if (ob->s.b.mixed_encoding)
+	{
+	  /* Determine the encoding for this FDE.  Note mixed encoded
+	     objects for later.  */
+	  this_cie = get_cie (this_fde);
+	  if (this_cie != last_cie)
+	    {
+	      last_cie = this_cie;
+	      encoding = get_cie_encoding (this_cie);
+	      base = base_from_object (encoding, ob);
+	    }
+	}
+
+      if (encoding == DW_EH_PE_absptr)
+	{
+	  pc_begin = ((_Unwind_Ptr *)this_fde->pc_begin)[0];
+	  pc_range = ((_Unwind_Ptr *)this_fde->pc_begin)[1];
+	  if (pc_begin == 0)
+	    continue;
+	}
+      else
+	{
+	  _Unwind_Ptr mask;
+	  const char *p;
+
+	  p = read_encoded_value_with_base (encoding, base,
+					    this_fde->pc_begin, &pc_begin);
+	  read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
+
+	  /* Take care to ignore link-once functions that were removed.
+	     In these cases, the function address will be NULL, but if
+	     the encoding is smaller than a pointer a true NULL may not
+	     be representable.  Assume 0 in the representable bits is NULL.  */
+	  mask = size_of_encoded_value (encoding);
+	  if (mask < sizeof (void *))
+	    mask = (1L << (mask << 3)) - 1;
+	  else
+	    mask = -1;
+
+	  if ((pc_begin & mask) == 0)
+	    continue;
+	}
+
+      if ((_Unwind_Ptr)pc - pc_begin < pc_range)
+        return this_fde;
+    }
+
+  return NULL;
+}
+
+/* Binary search for an FDE containing the given PC.  Here are three
+   implementations of increasing complexity.  */
+
+static inline fde *
+binary_search_unencoded_fdes (struct object *ob, void *pc)
+{
+  struct fde_vector *vec = ob->u.sort;
+  size_t lo, hi;
+      
+  for (lo = 0, hi = vec->count; lo < hi; )
+    {
+      size_t i = (lo + hi) / 2;
+      fde *f = vec->array[i];
+      void *pc_begin;
+      uaddr pc_range;
+
+      pc_begin = ((void **)f->pc_begin)[0];
+      pc_range = ((uaddr *)f->pc_begin)[1];
+
+      if (pc < pc_begin)
+	hi = i;
+      else if (pc >= pc_begin + pc_range)
+	lo = i + 1;
+      else
+	return f;
+    }
+
+  return NULL;
+}
+
+static inline fde *
+binary_search_single_encoding_fdes (struct object *ob, void *pc)
+{
+  struct fde_vector *vec = ob->u.sort;
+  int encoding = ob->s.b.encoding;
+  _Unwind_Ptr base = base_from_object (encoding, ob);
+  size_t lo, hi;
+      
+  for (lo = 0, hi = vec->count; lo < hi; )
+    {
+      size_t i = (lo + hi) / 2;
+      fde *f = vec->array[i];
+      _Unwind_Ptr pc_begin, pc_range;
+      const char *p;
+
+      p = read_encoded_value_with_base (encoding, base, f->pc_begin,
+					&pc_begin);
+      read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
+
+      if ((_Unwind_Ptr)pc < pc_begin)
+	hi = i;
+      else if ((_Unwind_Ptr)pc >= pc_begin + pc_range)
+	lo = i + 1;
+      else
+	return f;
+    }
+
+  return NULL;
+}
+
+static inline fde *
+binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
+{
+  struct fde_vector *vec = ob->u.sort;
+  size_t lo, hi;
+      
+  for (lo = 0, hi = vec->count; lo < hi; )
+    {
+      size_t i = (lo + hi) / 2;
+      fde *f = vec->array[i];
+      _Unwind_Ptr pc_begin, pc_range;
+      const char *p;
+      int encoding;
+
+      encoding = get_fde_encoding (f);
+      p = read_encoded_value_with_base (encoding,
+					base_from_object (encoding, ob),
+					f->pc_begin, &pc_begin);
+      read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
+
+      if ((_Unwind_Ptr)pc < pc_begin)
+	hi = i;
+      else if ((_Unwind_Ptr)pc >= pc_begin + pc_range)
+	lo = i + 1;
+      else
+	return f;
+    }
+
+  return NULL;
+}
+
+static fde *
+search_object (struct object* ob, void *pc)
+{
+  /* If the data hasn't been sorted, try to do this now.  We may have
+     more memory available than last time we tried.  */
+  if (! ob->s.b.sorted)
+    {
+      init_object (ob);
+
+      /* Despite the above comment, the normal reason to get here is
+	 that we've not processed this object before.  A quick range
+	 check is in order.  */
+      if (pc < ob->pc_begin)
+	return NULL;
+    }
+
+  if (ob->s.b.sorted)
+    {
+      if (ob->s.b.mixed_encoding)
+	return binary_search_mixed_encoding_fdes (ob, pc);
+      else if (ob->s.b.encoding == DW_EH_PE_absptr)
+	return binary_search_unencoded_fdes (ob, pc);
+      else
+	return binary_search_single_encoding_fdes (ob, pc);
+    }
+  else
+    {
+      /* Long slow labourious linear search, cos we've no memory.  */
+      if (ob->s.b.from_array)
+        {
+          fde **p;
+	  for (p = ob->u.array; *p ; p++)
+	    {
+	      fde *f = linear_search_fdes (ob, *p, pc);
+              if (f)
+		return f;
+            }
+	  return NULL;
+	}
+      else
+	return linear_search_fdes (ob, ob->u.single, pc);
+    }
+}
+
+fde *
+_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
+{
+  struct object *ob;
+  fde *f = NULL;
+
+  init_object_mutex_once ();
+  __gthread_mutex_lock (&object_mutex);
+
+  /* Linear search through the classified objects, to find the one
+     containing the pc.  Note that pc_begin is sorted decending, and
+     we expect objects to be non-overlapping.  */
+  for (ob = seen_objects; ob; ob = ob->next)
+    if (pc >= ob->pc_begin)
+      {
+	f = search_object (ob, pc);
+	if (f)
+	  goto fini;
+	break;
+      }
+
+  /* Classify and search the objects we've not yet processed.  */
+  while ((ob = unseen_objects))
+    {
+      struct object **p;
+
+      unseen_objects = ob->next;
+      f = search_object (ob, pc);
+
+      /* Insert the object into the classified list.  */
+      for (p = &seen_objects; *p ; p = &(*p)->next)
+	if ((*p)->pc_begin < ob->pc_begin)
+	  break;
+      ob->next = *p;
+      *p = ob;
+
+      if (f)
+	goto fini;
+    }
+
+ fini:
+  __gthread_mutex_unlock (&object_mutex);
+
+  if (f)
+    {
+      int encoding;
+
+      bases->tbase = ob->tbase;
+      bases->dbase = ob->dbase;
+
+      encoding = ob->s.b.encoding;
+      if (ob->s.b.mixed_encoding)
+	encoding = get_fde_encoding (f);
+      read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
+				    f->pc_begin, (_Unwind_Ptr *)&bases->func);
+    }
+
+  return f;
+}
--- libc/sysdeps/generic/unwind-dw2-fde.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/generic/unwind-dw2-fde.h	Mon Aug  6 07:59:59 2001
@@ -0,0 +1,165 @@
+/* Subroutines needed for unwinding stack frames for exception handling.  */
+/* 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.  */
+
+
+struct fde_vector
+{
+  void *orig_data;
+  size_t count;
+  struct dwarf_fde *array __flexarr;
+};
+
+#ifdef _LIBC
+#include <gccframe.h>
+#else
+struct object
+{
+  void *pc_begin;
+  void *tbase;
+  void *dbase;
+  union {
+    struct dwarf_fde *single;
+    struct dwarf_fde **array;
+    struct fde_vector *sort;
+  } u;
+
+  union {
+    struct {
+      unsigned long sorted : 1;
+      unsigned long from_array : 1;
+      unsigned long mixed_encoding : 1;
+      unsigned long encoding : 8;
+      /* ??? Wish there was an easy way to detect a 64-bit host here;
+	 we've got 32 bits left to play with... */
+      unsigned long count : 21;
+    } b;
+    size_t i;
+  } s;
+
+  struct object *next;
+};
+#endif
+
+/* This is the original definition of struct object.  While the struct
+   itself was opaque to users, they did know how large it was, and
+   allocate one statically in crtbegin for each DSO.  Keep this around
+   so that we're aware of the static size limitations for the new struct.  */
+struct old_object
+{
+  void *pc_begin;
+  void *pc_end;
+  struct dwarf_fde *fde_begin;
+  struct dwarf_fde **fde_array;
+  size_t count;
+  struct old_object *next;
+};
+
+struct dwarf_eh_bases
+{
+  void *tbase;
+  void *dbase;
+  void *func;
+};
+
+
+extern void __register_frame_info_bases (void *, struct object *,
+					 void *, void *);
+extern void __register_frame_info (void *, struct object *);
+extern void __register_frame (void *);
+extern void __register_frame_info_table_bases (void *, struct object *,
+					       void *, void *);
+extern void __register_frame_info_table (void *, struct object *);
+extern void __register_frame_table (void *);
+extern void *__deregister_frame_info (void *);
+extern void *__deregister_frame_info_bases (void *);
+extern void __deregister_frame (void *);
+
+
+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;
+  unsigned char augmentation __flexarr;
+} __attribute__ ((packed, aligned (__alignof__ (void *))));
+
+/* The first few fields of an FDE.  */
+struct dwarf_fde
+{
+  uword length;
+  sword CIE_delta;
+  unsigned char pc_begin __flexarr;
+} __attribute__ ((packed, aligned (__alignof__ (void *))));
+
+typedef struct dwarf_fde fde;
+
+/* Locate the CIE for a given FDE.  */
+
+static inline struct dwarf_cie *
+get_cie (struct dwarf_fde *f)
+{
+  return (void *)&f->CIE_delta - f->CIE_delta;
+}
+
+static inline fde *
+next_fde (fde *f)
+{
+  return (fde *)((char *)f + f->length + sizeof (f->length));
+}
+
+extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
--- libc/sysdeps/generic/unwind-dw2.c.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/generic/unwind-dw2.c	Mon Aug  6 08:03:52 2001
@@ -0,0 +1,1207 @@
+/* DWARF2 exception handling and frame unwind runtime interface routines.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   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.  */
+
+#ifdef _LIBC
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <libintl.h>
+#include <dwarf2.h>
+#include <unwind.h>
+#include <unwind-pe.h>
+#include <unwind-dw2-fde.h>
+#else
+#include "tconfig.h"
+#include "tsystem.h"
+#include "dwarf2.h"
+#include "unwind.h"
+#include "unwind-pe.h"
+#include "unwind-dw2-fde.h"
+#include "gthr.h"
+#endif
+
+#if !USING_SJLJ_EXCEPTIONS
+
+#ifndef STACK_GROWS_DOWNWARD
+#define STACK_GROWS_DOWNWARD 0
+#else
+#undef STACK_GROWS_DOWNWARD
+#define STACK_GROWS_DOWNWARD 1
+#endif
+
+/* A target can override (perhaps for backward compatibility) how
+   many dwarf2 columns are unwound.  */
+#ifndef DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
+#endif
+
+/* This is the register and unwind state for a particular frame.  */
+struct _Unwind_Context
+{
+  void *reg[DWARF_FRAME_REGISTERS+1];
+  void *cfa;
+  void *ra;
+  void *lsda;
+  struct dwarf_eh_bases bases;
+  _Unwind_Word args_size;
+};
+
+#ifndef _LIBC
+/* Byte size of every register managed by these routines.  */
+static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
+#endif
+
+
+/* The result of interpreting the frame unwind info for a frame.
+   This is all symbolic at this point, as none of the values can
+   be resolved until the target pc is located.  */
+typedef struct
+{
+  /* Each register save state can be described in terms of a CFA slot,
+     another register, or a location expression.  */
+  struct frame_state_reg_info
+  {
+    struct {
+      union {
+	unsigned int reg;
+	_Unwind_Sword offset;
+	const unsigned char *exp;
+      } loc;
+      enum {
+	REG_UNSAVED,
+	REG_SAVED_OFFSET,
+	REG_SAVED_REG,
+	REG_SAVED_EXP,
+      } how;
+    } reg[DWARF_FRAME_REGISTERS+1];
+
+    /* Used to implement DW_CFA_remember_state.  */
+    struct frame_state_reg_info *prev;
+  } regs;
+
+  /* The CFA can be described in terms of a reg+offset or a
+     location expression.  */
+  _Unwind_Sword cfa_offset;
+  _Unwind_Word cfa_reg;
+  const unsigned char *cfa_exp;
+  enum {
+    CFA_UNSET,
+    CFA_REG_OFFSET,
+    CFA_EXP,
+  } cfa_how;
+
+  /* The PC described by the current frame state.  */
+  void *pc;
+
+  /* The information we care about from the CIE/FDE.  */
+  _Unwind_Personality_Fn personality;
+  signed int data_align;
+  unsigned int code_align;
+  unsigned char retaddr_column;
+  unsigned char fde_encoding;
+  unsigned char lsda_encoding;
+  unsigned char saw_z;
+  void *eh_ptr;
+} _Unwind_FrameState;
+
+/* Read unaligned data from the instruction buffer.  */
+
+union unaligned
+{
+  void *p;
+  unsigned u2 __attribute__ ((mode (HI)));
+  unsigned u4 __attribute__ ((mode (SI)));
+  unsigned u8 __attribute__ ((mode (DI)));
+  signed s2 __attribute__ ((mode (HI)));
+  signed s4 __attribute__ ((mode (SI)));
+  signed s8 __attribute__ ((mode (DI)));
+} __attribute__ ((packed));
+
+static inline void *
+read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
+
+static inline int
+read_1u (const void *p) { return *(const unsigned char *)p; }
+
+static inline int
+read_1s (const void *p) { return *(const signed char *)p; }
+
+static inline int
+read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
+
+static inline int
+read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
+
+static inline unsigned int
+read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
+
+static inline int
+read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
+
+static inline unsigned long
+read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
+
+static inline unsigned long
+read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
+
+/* Get the value of register REG as saved in CONTEXT.  */
+
+inline _Unwind_Word
+_Unwind_GetGR (struct _Unwind_Context *context, int index)
+{
+  /* This will segfault if the register hasn't been saved.  */
+  return * (_Unwind_Word *) context->reg[index];
+}
+
+/* Overwrite the saved value for register REG in CONTEXT with VAL.  */
+
+inline void
+_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
+{
+  * (_Unwind_Word *) context->reg[index] = val;
+}
+
+/* Retrieve the return address for CONTEXT.  */
+
+inline _Unwind_Ptr
+_Unwind_GetIP (struct _Unwind_Context *context)
+{
+  return (_Unwind_Ptr) context->ra;
+}
+
+/* Overwrite the return address for CONTEXT with VAL.  */
+
+inline void
+_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
+{
+  context->ra = (void *) val;
+}
+
+void *
+_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
+{
+  return context->lsda;
+}
+
+_Unwind_Ptr
+_Unwind_GetRegionStart (struct _Unwind_Context *context)
+{
+  return (_Unwind_Ptr) context->bases.func;
+}
+
+#ifndef __ia64__
+_Unwind_Ptr
+_Unwind_GetDataRelBase (struct _Unwind_Context *context)
+{
+  return (_Unwind_Ptr) context->bases.dbase;
+}
+
+_Unwind_Ptr
+_Unwind_GetTextRelBase (struct _Unwind_Context *context)
+{
+  return (_Unwind_Ptr) context->bases.tbase;
+}
+#endif
+
+/* Extract any interesting information from the CIE for the translation
+   unit F belongs to.  Return a pointer to the byte after the augmentation,
+   or NULL if we encountered an undecipherable augmentation.  */
+
+static const unsigned char *
+extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
+		  _Unwind_FrameState *fs)
+{
+  const unsigned char *aug = cie->augmentation;
+  const unsigned char *p = aug + strlen (aug) + 1;
+  const unsigned char *ret = NULL;
+  _Unwind_Ptr tmp;
+
+  /* g++ v2 "eh" has pointer immediately following augmentation string,
+     so it must be handled first.  */
+  if (aug[0] == 'e' && aug[1] == 'h')
+    {
+      fs->eh_ptr = read_pointer (p);
+      p += sizeof (void *);
+      aug += 2;
+    }
+
+  /* Immediately following the augmentation are the code and
+     data alignment and return address column.  */
+  p = read_uleb128 (p, &tmp); fs->code_align = tmp;
+  p = read_sleb128 (p, &tmp); fs->data_align = (saddr) tmp;
+  fs->retaddr_column = *p++;
+  fs->lsda_encoding = DW_EH_PE_omit;
+
+  /* If the augmentation starts with 'z', then a uleb128 immediately
+     follows containing the length of the augmentation field following
+     the size.  */
+  if (*aug == 'z')
+    {
+      p = read_uleb128 (p, &tmp);
+      ret = p + tmp;
+
+      fs->saw_z = 1;
+      ++aug;
+    }
+
+  /* Iterate over recognized augmentation subsequences.  */
+  while (*aug != '\0')
+    {
+      /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
+      if (aug[0] == 'L')
+	{
+	  fs->lsda_encoding = *p++;
+	  aug += 1;
+	}
+
+      /* "R" indicates a byte indicating how FDE addresses are encoded.  */
+      else if (aug[0] == 'R')
+	{
+	  fs->fde_encoding = *p++;
+	  aug += 1;
+	}
+
+      /* "P" indicates a personality routine in the CIE augmentation.  */
+      else if (aug[0] == 'P')
+	{
+	  p = read_encoded_value (context, *p, p + 1,
+				  (_Unwind_Ptr *) &fs->personality);
+	  aug += 1;
+	}
+
+      /* Otherwise we have an unknown augmentation string.
+	 Bail unless we saw a 'z' prefix.  */
+      else
+	return ret;
+    }
+
+  return ret ? ret : p;
+}
+
+#ifndef _LIBC
+/* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
+   onto the stack to start.  */
+
+static _Unwind_Word
+execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
+		  struct _Unwind_Context *context, _Unwind_Word initial)
+{
+  _Unwind_Word stack[64];	/* ??? Assume this is enough. */
+  int stack_elt;
+
+  stack[0] = initial;
+  stack_elt = 1;
+
+  while (op_ptr < op_end)
+    {
+      enum dwarf_location_atom op = *op_ptr++;
+      _Unwind_Word result = 0, reg;
+      _Unwind_Sword offset;
+      _Unwind_Ptr ptrtmp;
+
+      switch (op)
+	{
+	case DW_OP_lit0:
+	case DW_OP_lit1:
+	case DW_OP_lit2:
+	case DW_OP_lit3:
+	case DW_OP_lit4:
+	case DW_OP_lit5:
+	case DW_OP_lit6:
+	case DW_OP_lit7:
+	case DW_OP_lit8:
+	case DW_OP_lit9:
+	case DW_OP_lit10:
+	case DW_OP_lit11:
+	case DW_OP_lit12:
+	case DW_OP_lit13:
+	case DW_OP_lit14:
+	case DW_OP_lit15:
+	case DW_OP_lit16:
+	case DW_OP_lit17:
+	case DW_OP_lit18:
+	case DW_OP_lit19:
+	case DW_OP_lit20:
+	case DW_OP_lit21:
+	case DW_OP_lit22:
+	case DW_OP_lit23:
+	case DW_OP_lit24:
+	case DW_OP_lit25:
+	case DW_OP_lit26:
+	case DW_OP_lit27:
+	case DW_OP_lit28:
+	case DW_OP_lit29:
+	case DW_OP_lit30:
+	case DW_OP_lit31:
+	  result = op - DW_OP_lit0;
+	  break;
+
+	case DW_OP_addr:
+	  result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
+	  op_ptr += sizeof (void *);
+	  break;
+
+	case DW_OP_const1u:
+	  result = read_1u (op_ptr);
+	  op_ptr += 1;
+	  break;
+	case DW_OP_const1s:
+	  result = read_1s (op_ptr);
+	  op_ptr += 1;
+	  break;
+	case DW_OP_const2u:
+	  result = read_2u (op_ptr);
+	  op_ptr += 2;
+	  break;
+	case DW_OP_const2s:
+	  result = read_2s (op_ptr);
+	  op_ptr += 2;
+	  break;
+	case DW_OP_const4u:
+	  result = read_4u (op_ptr);
+	  op_ptr += 4;
+	  break;
+	case DW_OP_const4s:
+	  result = read_4s (op_ptr);
+	  op_ptr += 4;
+	  break;
+	case DW_OP_const8u:
+	  result = read_8u (op_ptr);
+	  op_ptr += 8;
+	  break;
+	case DW_OP_const8s:
+	  result = read_8s (op_ptr);
+	  op_ptr += 8;
+	  break;
+	case DW_OP_constu:
+	  op_ptr = read_uleb128 (op_ptr, &ptrtmp);
+	  result = ptrtmp;
+	  break;
+	case DW_OP_consts:
+	  op_ptr = read_sleb128 (op_ptr, &ptrtmp);
+	  result = (saddr)ptrtmp;
+	  break;
+
+	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:
+	  result = _Unwind_GetGR (context, op - DW_OP_reg0);
+	  break;
+	case DW_OP_regx:
+	  op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
+	  result = _Unwind_GetGR (context, reg);
+	  break;
+
+	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:
+	  op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
+	  result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
+	  break;
+	case DW_OP_bregx:
+	  op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
+	  op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
+	  result = _Unwind_GetGR (context, reg) + offset;
+	  break;
+
+	case DW_OP_dup:
+	  if (stack_elt < 1)
+	    abort ();
+	  result = stack[stack_elt - 1];
+	  break;
+
+	case DW_OP_drop:
+	  if (--stack_elt < 0)
+	    abort ();
+	  goto no_push;
+
+	case DW_OP_pick:
+	  offset = *op_ptr++;
+	  if (offset >= stack_elt - 1)
+	    abort ();
+	  result = stack[stack_elt - 1 - offset];
+	  break;
+
+	case DW_OP_over:
+	  if (stack_elt < 2)
+	    abort ();
+	  result = stack[stack_elt - 2];
+	  break;
+
+	case DW_OP_rot:
+	  {
+	    _Unwind_Word t1, t2, t3;
+
+	    if (stack_elt < 3)
+	      abort ();
+	    t1 = stack[stack_elt - 1];
+	    t2 = stack[stack_elt - 2];
+	    t3 = stack[stack_elt - 3];
+	    stack[stack_elt - 1] = t2;
+	    stack[stack_elt - 2] = t3;
+	    stack[stack_elt - 3] = t1;
+	    goto no_push;
+	  }
+
+	case DW_OP_deref:
+	case DW_OP_deref_size:
+	case DW_OP_abs:
+	case DW_OP_neg:
+	case DW_OP_not:
+	case DW_OP_plus_uconst:
+	  /* Unary operations.  */
+	  if (--stack_elt < 0)
+	    abort ();
+	  result = stack[stack_elt];
+
+	  switch (op)
+	    {
+	    case DW_OP_deref:
+	      {
+		void *ptr = (void *)(_Unwind_Ptr) result;
+		result = (_Unwind_Ptr) read_pointer (ptr);
+	      }
+	      break;
+
+	    case DW_OP_deref_size:
+	      {
+		void *ptr = (void *)(_Unwind_Ptr) result;
+		switch (*op_ptr++)
+		  {
+		  case 1:
+		    result = read_1u (ptr);
+		    break;
+		  case 2:
+		    result = read_2u (ptr);
+		    break;
+		  case 4:
+		    result = read_4u (ptr);
+		    break;
+		  case 8:
+		    result = read_8u (ptr);
+		    break;
+		  default:
+		    abort ();
+		  }
+	      }
+	      break;
+
+	    case DW_OP_abs:
+	      if ((_Unwind_Sword) result < 0)
+		result = -result;
+	      break;
+	    case DW_OP_neg:
+	      result = -result;
+	      break;
+	    case DW_OP_not:
+	      result = ~result;
+	      break;
+	    case DW_OP_plus_uconst:
+	      op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
+	      result += reg;
+	      break;
+	    /* Avoid warnings.  */
+	    default:
+	      break;
+	    }
+	  break;
+
+	case DW_OP_and:
+	case DW_OP_div:
+	case DW_OP_minus:
+	case DW_OP_mod:
+	case DW_OP_mul:
+	case DW_OP_or:
+	case DW_OP_plus:
+	case DW_OP_le:
+	case DW_OP_ge:
+	case DW_OP_eq:
+	case DW_OP_lt:
+	case DW_OP_gt:
+	case DW_OP_ne:
+	  {
+	    /* Binary operations.  */
+	    _Unwind_Word first, second;
+	  if ((stack_elt -= 2) < 0)
+	    abort ();
+	  second = stack[stack_elt];
+	  first = stack[stack_elt + 1];
+
+	  switch (op)
+	    {
+	    case DW_OP_and:
+	      result = second & first;
+	      break;
+	    case DW_OP_div:
+	      result = (_Unwind_Sword)second / (_Unwind_Sword)first;
+	      break;
+	    case DW_OP_minus:
+	      result = second - first;
+	      break;
+	    case DW_OP_mod:
+	      result = (_Unwind_Sword)second % (_Unwind_Sword)first;
+	      break;
+	    case DW_OP_mul:
+	      result = second * first;
+	      break;
+	    case DW_OP_or:
+	      result = second | first;
+	      break;
+	    case DW_OP_plus:
+	      result = second + first;
+	      break;
+	    case DW_OP_shl:
+	      result = second << first;
+	      break;
+	    case DW_OP_shr:
+	      result = second >> first;
+	      break;
+	    case DW_OP_shra:
+	      result = (_Unwind_Sword)second >> first;
+	      break;
+	    case DW_OP_xor:
+	      result = second ^ first;
+	      break;
+	    case DW_OP_le:
+	      result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
+	      break;
+	    case DW_OP_ge:
+	      result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
+	      break;
+	    case DW_OP_eq:
+	      result = (_Unwind_Sword)first == (_Unwind_Sword)second;
+	      break;
+	    case DW_OP_lt:
+	      result = (_Unwind_Sword)first < (_Unwind_Sword)second;
+	      break;
+	    case DW_OP_gt:
+	      result = (_Unwind_Sword)first > (_Unwind_Sword)second;
+	      break;
+	    case DW_OP_ne:
+	      result = (_Unwind_Sword)first != (_Unwind_Sword)second;
+	      break;
+	    default:
+	      /* Avoid warnings.  */
+	      break;
+	    }
+	  }
+	  break;
+
+	case DW_OP_skip:
+	  offset = read_2s (op_ptr);
+	  op_ptr += 2;
+	  op_ptr += offset;
+	  goto no_push;
+
+	case DW_OP_bra:
+	  if (--stack_elt < 0)
+	    abort ();
+	  offset = read_2s (op_ptr);
+	  op_ptr += 2;
+	  if (stack[stack_elt] != 0)
+	    op_ptr += offset;
+	  goto no_push;
+
+	case DW_OP_nop:
+	  goto no_push;
+
+	default:
+	  abort ();
+	}
+
+      /* Most things push a result value.  */
+      if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
+	abort ();
+      stack[++stack_elt] = result;
+    no_push:;
+    }
+
+  /* We were executing this program to get a value.  It should be
+     at top of stack.  */
+  if (--stack_elt < 0)
+    abort ();
+  return stack[stack_elt];
+}
+#endif
+
+/* Decode DWARF 2 call frame information. Takes pointers the
+   instruction sequence to decode, current register information and
+   CIE info, and the PC range to evaluate.  */
+
+static void
+execute_cfa_program (const unsigned char *insn_ptr,
+		     const unsigned char *insn_end,
+		     struct _Unwind_Context *context,
+		     _Unwind_FrameState *fs)
+{
+  struct frame_state_reg_info *unused_rs = NULL;
+
+  /* Don't allow remember/restore between CIE and FDE programs.  */
+  fs->regs.prev = NULL;
+
+  while (insn_ptr < insn_end && fs->pc < context->ra)
+    {
+      unsigned char insn = *insn_ptr++;
+      _Unwind_Word reg;
+      _Unwind_Sword offset;
+      _Unwind_Ptr ptrtmp;
+
+      if (insn & DW_CFA_advance_loc)
+	fs->pc += (insn & 0x3f) * fs->code_align;
+      else if (insn & DW_CFA_offset)
+	{
+	  reg = insn & 0x3f;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  offset = ptrtmp * fs->data_align;
+	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[reg].loc.offset = offset;
+	}
+      else if (insn & DW_CFA_restore)
+	{
+	  reg = insn & 0x3f;
+	  fs->regs.reg[reg].how = REG_UNSAVED;
+	}
+      else switch (insn)
+	{
+	case DW_CFA_set_loc:
+	  insn_ptr = read_encoded_value (context, fs->fde_encoding,
+					 insn_ptr, (_Unwind_Ptr *) &fs->pc);
+	  break;
+
+	case DW_CFA_advance_loc1:
+	  fs->pc += read_1u (insn_ptr) * fs->code_align;
+	  insn_ptr += 1;
+	  break;
+	case DW_CFA_advance_loc2:
+	  fs->pc += read_2u (insn_ptr) * fs->code_align;
+	  insn_ptr += 2;
+	  break;
+	case DW_CFA_advance_loc4:
+	  fs->pc += read_4u (insn_ptr) * fs->code_align;
+	  insn_ptr += 4;
+	  break;
+
+	case DW_CFA_offset_extended:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  offset = ptrtmp * fs->data_align;
+	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[reg].loc.offset = offset;
+	  break;
+
+	case DW_CFA_restore_extended:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  fs->regs.reg[reg].how = REG_UNSAVED;
+	  break;
+
+	case DW_CFA_undefined:
+	case DW_CFA_same_value:
+	case DW_CFA_nop:
+	  break;
+
+	case DW_CFA_register:
+	  {
+	    _Unwind_Word reg2;
+	    insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	    insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
+	    fs->regs.reg[reg].how = REG_SAVED_REG;
+	    fs->regs.reg[reg].loc.reg = reg2;
+	  }
+	  break;
+      
+	case DW_CFA_remember_state:
+	  {
+	    struct frame_state_reg_info *new_rs;
+	    if (unused_rs)
+	      {
+		new_rs = unused_rs;
+		unused_rs = unused_rs->prev;
+	      }
+	    else
+	      new_rs = alloca (sizeof (struct frame_state_reg_info));
+
+	    *new_rs = fs->regs;
+	    fs->regs.prev = new_rs;
+	  }
+	  break;
+
+	case DW_CFA_restore_state:
+	  {
+	    struct frame_state_reg_info *old_rs = fs->regs.prev;
+	    fs->regs = *old_rs;
+	    old_rs->prev = unused_rs;
+	    unused_rs = old_rs;
+	  }
+	  break;
+
+	case DW_CFA_def_cfa:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = ptrtmp;
+	  fs->cfa_how = CFA_REG_OFFSET;
+	  break;
+
+	case DW_CFA_def_cfa_register:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_reg = ptrtmp;
+	  fs->cfa_how = CFA_REG_OFFSET;
+	  break;
+
+	case DW_CFA_def_cfa_offset:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = ptrtmp;
+	  /* cfa_how deliberately not set.  */
+	  break;
+
+	case DW_CFA_def_cfa_expression:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_exp = insn_ptr;
+	  fs->cfa_how = CFA_EXP;
+	  insn_ptr += ptrtmp;
+	  break;
+
+	case DW_CFA_expression:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->regs.reg[reg].how = REG_SAVED_EXP;
+	  fs->regs.reg[reg].loc.exp = insn_ptr;
+	  insn_ptr += ptrtmp;
+	  break;
+
+	  /* From the 2.1 draft.  */
+	case DW_CFA_offset_extended_sf:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
+	  offset = (saddr)ptrtmp * fs->data_align;
+	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[reg].loc.offset = offset;
+	  break;
+	  
+	case DW_CFA_def_cfa_sf:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_reg = ptrtmp;
+	  insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = (saddr)ptrtmp;
+	  fs->cfa_how = CFA_REG_OFFSET;
+	  break;
+
+	case DW_CFA_def_cfa_offset_sf:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = ptrtmp;
+	  /* cfa_how deliberately not set.  */
+	  break;
+
+	case DW_CFA_GNU_window_save:
+	  /* ??? Hardcoded for SPARC register window configuration.  */
+	  for (reg = 16; reg < 32; ++reg)
+	    {
+	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+	      fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
+	    }
+	  break;
+
+	case DW_CFA_GNU_args_size:
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  context->args_size = ptrtmp;
+	  break;
+
+	case DW_CFA_GNU_negative_offset_extended:
+	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
+	     older PowerPC code.  */
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  offset = ptrtmp * fs->data_align;
+	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[reg].loc.offset = -offset;
+	  break;
+
+	default:
+	  abort ();
+	}
+    }
+}
+
+static _Unwind_Reason_Code
+uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  struct dwarf_fde *fde;
+  struct dwarf_cie *cie;
+  const unsigned char *aug, *insn, *end;
+
+  memset (fs, 0, sizeof (*fs));
+  context->args_size = 0;
+  context->lsda = 0;
+
+  fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
+  if (fde == NULL)
+    {
+      /* Couldn't find frame unwind info for this function.  Try a
+	 target-specific fallback mechanism.  This will necessarily
+	 not profide a personality routine or LSDA.  */
+#ifdef MD_FALLBACK_FRAME_STATE_FOR
+      MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
+      return _URC_END_OF_STACK;
+    success:
+      return _URC_NO_REASON;
+#else
+      return _URC_END_OF_STACK;
+#endif
+    }
+
+  fs->pc = context->bases.func;
+
+  cie = get_cie (fde);
+  insn = extract_cie_info (cie, context, fs);
+  if (insn == NULL)
+    /* CIE contained unknown augmentation.  */
+    return _URC_FATAL_PHASE1_ERROR;
+
+  /* First decode all the insns in the CIE.  */
+  end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
+  execute_cfa_program (insn, end, context, fs);
+
+  /* Locate augmentation for the fde.  */
+  aug = (unsigned char *)fde + sizeof (*fde);
+  aug += 2 * size_of_encoded_value (fs->fde_encoding);
+  insn = NULL;
+  if (fs->saw_z)
+    {
+      _Unwind_Ptr i;
+      aug = read_uleb128 (aug, &i);
+      insn = aug + i;
+    }
+  if (fs->lsda_encoding != DW_EH_PE_omit)
+    aug = read_encoded_value (context, fs->lsda_encoding, aug,
+			      (_Unwind_Ptr *) &context->lsda);
+
+  /* Then the insns in the FDE up to our target PC.  */
+  if (insn == NULL)
+    insn = aug;
+  end = (unsigned char *) next_fde (fde);
+  execute_cfa_program (insn, end, context, fs);
+
+  return _URC_NO_REASON;
+}
+
+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];
+} frame_state;
+
+struct frame_state * __frame_state_for (void *, struct frame_state *);
+
+/* Called from pre-G++ 3.0 __throw to find the registers to restore for
+   a given PC_TARGET.  The caller should allocate a local variable of
+   `struct frame_state' and pass its address to STATE_IN.  */
+
+struct frame_state *
+__frame_state_for (void *pc_target, struct frame_state *state_in)
+{
+  struct _Unwind_Context context;
+  _Unwind_FrameState fs;
+  int reg;
+
+  memset (&context, 0, sizeof (struct _Unwind_Context));
+  context.ra = pc_target + 1;
+
+  if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
+    return 0;
+
+  /* We have no way to pass a location expression for the CFA to our
+     caller.  It wouldn't understand it anyway.  */
+  if (fs.cfa_how == CFA_EXP)
+    return 0;
+
+  for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++)
+    {
+      state_in->saved[reg] = fs.regs.reg[reg].how;
+      switch (state_in->saved[reg])
+	{
+	case REG_SAVED_REG:
+	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
+	  break;
+	case REG_SAVED_OFFSET:
+	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
+	  break;
+	default:
+	  state_in->reg_or_offset[reg] = 0;
+	  break;
+	}
+    }
+
+  state_in->cfa_offset = fs.cfa_offset;
+  state_in->cfa_reg = fs.cfa_reg;
+  state_in->retaddr_column = fs.retaddr_column;
+  state_in->args_size = context.args_size;
+  state_in->eh_ptr = fs.eh_ptr;
+
+  return state_in;
+}
+
+#ifndef _LIBC
+
+static void
+uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  struct _Unwind_Context orig_context = *context;
+  void *cfa;
+  long i;
+
+  /* Compute this frame's CFA.  */
+  switch (fs->cfa_how)
+    {
+    case CFA_REG_OFFSET:
+      /* Special handling here: Many machines do not use a frame pointer,
+	 and track the CFA only through offsets from the stack pointer from
+	 one frame to the next.  In this case, the stack pointer is never
+	 stored, so it has no saved address in the context.  What we do 
+	 have is the CFA from the previous stack frame.  */
+      if (context->reg[fs->cfa_reg] == NULL)
+	cfa = context->cfa;
+      else
+	cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
+      cfa += fs->cfa_offset;
+      break;
+
+    case CFA_EXP:
+      /* ??? No way of knowing what register number is the stack pointer
+	 to do the same sort of handling as above.  Assume that if the
+	 CFA calculation is so complicated as to require a stack program
+	 that this will not be a problem.  */
+      {
+	const unsigned char *exp = fs->cfa_exp;
+	_Unwind_Ptr len;
+
+	exp = read_uleb128 (exp, &len);
+	cfa = (void *) (_Unwind_Ptr)
+	  execute_stack_op (exp, exp + len, context, 0);
+	break;
+      }
+
+    default:
+      abort ();
+    }
+  context->cfa = cfa;
+
+  /* Compute the addresses of all registers saved in this frame.  */
+  for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
+    switch (fs->regs.reg[i].how)
+      {
+      case REG_UNSAVED:
+	break;
+      case REG_SAVED_OFFSET:
+	context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
+	break;
+      case REG_SAVED_REG:
+	context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
+	break;
+      case REG_SAVED_EXP:
+	{
+	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
+	  _Unwind_Ptr len;
+	  _Unwind_Ptr val;
+
+	  exp = read_uleb128 (exp, &len);
+	  val = execute_stack_op (exp, exp + len, &orig_context,
+				  (_Unwind_Ptr) cfa);
+	  context->reg[i] = (void *) val;
+	}
+	break;
+      }
+}
+
+static void
+uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  uw_update_context_1 (context, fs);
+
+  /* Compute the return address now, since the return address column
+     can change from frame to frame.  */
+  context->ra = __builtin_extract_return_addr
+    ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
+}
+
+/* Fill in CONTEXT for top-of-stack.  The only valid registers at this
+   level will be the return address and the CFA.  */
+   
+#define uw_init_context(CONTEXT)					\
+do {									\
+  /* Do any necessary initialization to access arbitrary stack frames.	\
+     On the SPARC, this means flushing the register windows.  */	\
+  __builtin_unwind_init ();						\
+  uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),			\
+		     __builtin_return_address (0));			\
+} while (0)
+
+static void
+uw_init_context_1 (struct _Unwind_Context *context,
+		   void *outer_cfa, void *outer_ra)
+{
+  void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
+  _Unwind_FrameState fs;
+
+  memset (context, 0, sizeof (struct _Unwind_Context));
+  context->ra = ra;
+
+  if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
+    abort ();
+
+  /* Force the frame state to use the known cfa value.  */
+  context->cfa = outer_cfa;
+  fs.cfa_how = CFA_REG_OFFSET;
+  fs.cfa_reg = 0;
+  fs.cfa_offset = 0;
+
+  uw_update_context_1 (context, &fs);
+
+  /* If the return address column was saved in a register in the
+     initialization context, then we can't see it in the given
+     call frame data.  So have the initialization context tell us.  */
+  context->ra = __builtin_extract_return_addr (outer_ra);
+}
+
+
+/* Install TARGET into CURRENT so that we can return to it.  This is a
+   macro because __builtin_eh_return must be invoked in the context of
+   our caller.  */
+
+#define uw_install_context(CURRENT, TARGET)				\
+do {									\
+  long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
+  void *handler = __builtin_frob_return_addr ((TARGET)->ra);		\
+  __builtin_eh_return (offset, handler);				\
+} while (0)
+
+static inline void
+init_dwarf_reg_size_table (void)
+{
+  __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
+}
+
+static long
+uw_install_context_1 (struct _Unwind_Context *current,
+		      struct _Unwind_Context *target)
+{
+  long i;
+
+#if __GTHREADS
+  {
+    static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
+    if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
+	|| dwarf_reg_size_table[0] == 0)
+      init_dwarf_reg_size_table ();
+  }
+#else
+  if (dwarf_reg_size_table[0] == 0)
+    init_dwarf_reg_size_table ();
+#endif
+
+  for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
+    {
+      void *c = current->reg[i];
+      void *t = target->reg[i];
+      if (t && c && t != c)
+	memcpy (c, t, dwarf_reg_size_table[i]);
+    }
+
+  /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
+  if (STACK_GROWS_DOWNWARD)
+    return target->cfa - current->cfa + target->args_size;
+  else
+    return current->cfa - target->cfa - target->args_size;
+}
+
+static inline _Unwind_Ptr
+uw_identify_context (struct _Unwind_Context *context)
+{
+  return _Unwind_GetIP (context);
+}
+
+
+#include "unwind.inc"
+
+#endif /* _LIBC */
+#endif /* !USING_SJLJ_EXCEPTIONS */
--- libc/sysdeps/generic/unwind-pe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/generic/unwind-pe.h	Mon Aug  6 04:54:54 2001
@@ -0,0 +1,272 @@
+/* Exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+   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.  */
+
+/* @@@ Really this should be out of line, but this also causes link
+   compatibility problems with the base ABI.  This is slightly better
+   than duplicating code, however.  */
+
+/* If using C++, references to abort have to be qualified with std::. */
+#if __cplusplus
+#define __gxx_abort std::abort
+#else
+#define __gxx_abort abort
+#endif
+
+/* Pointer encodings, from dwarf2.h.  */
+#define DW_EH_PE_absptr         0x00
+#define DW_EH_PE_omit           0xff
+
+#define DW_EH_PE_uleb128        0x01
+#define DW_EH_PE_udata2         0x02
+#define DW_EH_PE_udata4         0x03
+#define DW_EH_PE_udata8         0x04
+#define DW_EH_PE_sleb128        0x09
+#define DW_EH_PE_sdata2         0x0A
+#define DW_EH_PE_sdata4         0x0B
+#define DW_EH_PE_sdata8         0x0C
+#define DW_EH_PE_signed         0x08
+
+#define DW_EH_PE_pcrel          0x10
+#define DW_EH_PE_textrel        0x20
+#define DW_EH_PE_datarel        0x30
+#define DW_EH_PE_funcrel        0x40
+#define DW_EH_PE_aligned        0x50
+
+#define DW_EH_PE_indirect	0x80
+
+
+/* Given an encoding, return the number of bytes the format occupies.
+   This is only defined for fixed-size encodings, and so does not
+   include leb128.  */
+
+#ifndef _LIBC
+static
+#endif
+unsigned int
+size_of_encoded_value (unsigned char encoding)
+#if defined(_LIBC) && !defined(NO_BASE_OF_ENCODED_VALUE)
+;
+#else
+{
+  if (encoding == DW_EH_PE_omit)
+    return 0;
+
+  switch (encoding & 0x07)
+    {
+    case DW_EH_PE_absptr:
+      return sizeof (void *);
+    case DW_EH_PE_udata2:
+      return 2;
+    case DW_EH_PE_udata4:
+      return 4;
+    case DW_EH_PE_udata8:
+      return 8;
+    }
+  __gxx_abort ();
+}
+#endif
+
+#ifndef NO_BASE_OF_ENCODED_VALUE
+
+/* Given an encoding and an _Unwind_Context, return the base to which
+   the encoding is relative.  This base may then be passed to
+   read_encoded_value_with_base for use when the _Unwind_Context is
+   not available.  */
+
+static _Unwind_Ptr
+base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
+{
+  if (encoding == DW_EH_PE_omit)
+    return 0;
+
+  switch (encoding & 0x70)
+    {
+    case DW_EH_PE_absptr:
+    case DW_EH_PE_pcrel:
+    case DW_EH_PE_aligned:
+      return 0;
+
+    case DW_EH_PE_textrel:
+      return _Unwind_GetTextRelBase (context);
+    case DW_EH_PE_datarel:
+      return _Unwind_GetDataRelBase (context);
+    case DW_EH_PE_funcrel:
+      return _Unwind_GetRegionStart (context);
+    }
+  __gxx_abort ();
+}
+
+#endif
+
+/* Load an encoded value from memory at P.  The value is returned in VAL;
+   The function returns P incremented past the value.  BASE is as given
+   by base_of_encoded_value for this encoding in the appropriate context.  */
+
+#ifndef _LIBC
+static
+#endif
+const unsigned char *
+read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
+			      const unsigned char *p, _Unwind_Ptr *val)
+#if defined(_LIBC) && !defined(NO_BASE_OF_ENCODED_VALUE)
+;
+#else
+{
+  union unaligned
+    {
+      void *ptr;
+      unsigned u2 __attribute__ ((mode (HI)));
+      unsigned u4 __attribute__ ((mode (SI)));
+      unsigned u8 __attribute__ ((mode (DI)));
+      signed s2 __attribute__ ((mode (HI)));
+      signed s4 __attribute__ ((mode (SI)));
+      signed s8 __attribute__ ((mode (DI)));
+    } __attribute__((__packed__));
+
+  union unaligned *u = (union unaligned *) p;
+  _Unwind_Ptr result;
+
+  if (encoding == DW_EH_PE_aligned)
+    {
+      _Unwind_Ptr a = (_Unwind_Ptr)p;
+      a = (a + sizeof (void *) - 1) & - sizeof(void *);
+      result = *(_Unwind_Ptr *) a;
+      p = (const unsigned char *)(a + sizeof (void *));
+    }
+  else
+    {
+      switch (encoding & 0x0f)
+	{
+	case DW_EH_PE_absptr:
+	  result = (_Unwind_Ptr) u->ptr;
+	  p += sizeof (void *);
+	  break;
+
+	case DW_EH_PE_uleb128:
+	  {
+	    unsigned int shift = 0;
+	    unsigned char byte;
+
+	    result = 0;
+	    do
+	      {
+		byte = *p++;
+		result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
+		shift += 7;
+	      }
+	    while (byte & 0x80);
+	  }
+	  break;
+
+	case DW_EH_PE_sleb128:
+	  {
+	    unsigned int shift = 0;
+	    unsigned char byte;
+
+	    result = 0;
+	    do
+	      {
+		byte = *p++;
+		result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
+		shift += 7;
+	      }
+	    while (byte & 0x80);
+
+	    if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
+	      result |= -(1L << shift);
+	  }
+	  break;
+
+	case DW_EH_PE_udata2:
+	  result = u->u2;
+	  p += 2;
+	  break;
+	case DW_EH_PE_udata4:
+	  result = u->u4;
+	  p += 4;
+	  break;
+	case DW_EH_PE_udata8:
+	  result = u->u8;
+	  p += 8;
+	  break;
+
+	case DW_EH_PE_sdata2:
+	  result = u->s2;
+	  p += 2;
+	  break;
+	case DW_EH_PE_sdata4:
+	  result = u->s4;
+	  p += 4;
+	  break;
+	case DW_EH_PE_sdata8:
+	  result = u->s8;
+	  p += 8;
+	  break;
+
+	default:
+	  __gxx_abort ();
+	}
+
+      if (result != 0)
+	{
+	  result += ((encoding & 0x70) == DW_EH_PE_pcrel
+		     ? (_Unwind_Ptr)u : base);
+	  if (encoding & DW_EH_PE_indirect)
+	    result = *(_Unwind_Ptr *)result;
+	}
+    }
+
+  *val = result;
+  return p;
+}
+#endif
+
+#ifndef NO_BASE_OF_ENCODED_VALUE
+
+/* Like read_encoded_value_with_base, but get the base from the context
+   rather than providing it directly.  */
+
+static inline const unsigned char *
+read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
+		    const unsigned char *p, _Unwind_Ptr *val)
+{
+  return read_encoded_value_with_base (encoding,
+		base_of_encoded_value (encoding, context),
+		p, val);
+}
+
+#endif
+
+/* Read an unsigned leb128 value from P, store the value in VAL, return
+   P incremented past the value.  */
+
+static inline const unsigned char *
+read_uleb128 (const unsigned char *p, _Unwind_Ptr *val)
+{
+  return read_encoded_value_with_base (DW_EH_PE_uleb128, 0, p, val);
+}
+
+/* Similar, but read a signed leb128 value.  */
+
+static inline const unsigned char *
+read_sleb128 (const unsigned char *p, _Unwind_Ptr *val)
+{
+  return read_encoded_value_with_base (DW_EH_PE_sleb128, 0, p, val);
+}
--- libc/sysdeps/generic/unwind.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/generic/unwind.h	Sun May 13 03:10:02 2001
@@ -0,0 +1,191 @@
+/* Exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+   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 is derived from the C++ ABI for IA-64.  Where we diverge
+   for cross-architecture compatibility are noted with "@@@".  */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Level 1: Base ABI  */
+
+/* @@@ The IA-64 ABI uses uint64 throughout.  Most places this is
+   inefficient for 32-bit and smaller machines.  */
+typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
+typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
+
+/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
+   consumer of an exception.  We'll go along with this for now even on
+   32-bit machines.  We'll need to provide some other option for
+   16-bit machines and for machines with > 8 bits per byte.  */
+typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
+
+/* The unwind interface uses reason codes in several contexts to
+   identify the reasons for failures or other actions.  */
+typedef enum
+{
+  _URC_NO_REASON = 0,
+  _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+  _URC_FATAL_PHASE2_ERROR = 2,
+  _URC_FATAL_PHASE1_ERROR = 3,
+  _URC_NORMAL_STOP = 4,
+  _URC_END_OF_STACK = 5,
+  _URC_HANDLER_FOUND = 6,
+  _URC_INSTALL_CONTEXT = 7,
+  _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+
+/* The unwind interface uses a pointer to an exception header object
+   as its representation of an exception being thrown. In general, the
+   full representation of an exception object is language- and
+   implementation-specific, but it will be prefixed by a header
+   understood by the unwind interface.  */
+
+struct _Unwind_Exception;
+
+typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+					      struct _Unwind_Exception *);
+
+struct _Unwind_Exception
+{
+  _Unwind_Exception_Class exception_class;
+  _Unwind_Exception_Cleanup_Fn exception_cleanup;
+  _Unwind_Word private_1;
+  _Unwind_Word private_2;
+
+  /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
+     Taking that literally does not make much sense generically.  Instead we
+     provide the maximum alignment required by any type for the machine.  */
+} __attribute__((__aligned__));
+
+
+/* The ACTIONS argument to the personality routine is a bitwise OR of one
+   or more of the following constants.  */
+typedef int _Unwind_Action;
+
+#define _UA_SEARCH_PHASE	1
+#define _UA_CLEANUP_PHASE	2
+#define _UA_HANDLER_FRAME	4
+#define _UA_FORCE_UNWIND	8
+
+/* This is an opaque type used to refer to a system-specific data
+   structure used by the system unwinder. This context is created and
+   destroyed by the system, and passed to the personality routine
+   during unwinding.  */
+struct _Unwind_Context;
+
+/* Raise an exception, passing along the given exception object.  */
+extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
+
+/* Raise an exception for forced unwinding.  */
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+     (int, _Unwind_Action, _Unwind_Exception_Class,
+      struct _Unwind_Exception *, struct _Unwind_Context *, void *);
+
+extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
+						 _Unwind_Stop_Fn,
+						 void *);
+
+/* Helper to invoke the exception_cleanup routine.  */
+extern void _Unwind_DeleteException (struct _Unwind_Exception *);
+
+/* Resume propagation of an existing exception.  This is used after
+   e.g. executing cleanup code, and not to implement rethrowing.  */
+extern void _Unwind_Resume (struct _Unwind_Exception *);
+
+/* These functions are used for communicating information about the unwind
+   context (i.e. the unwind descriptors and the user register state) between
+   the unwind library and the personality routine and landing pad.  Only
+   selected registers maybe manipulated.  */
+
+extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
+extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
+
+extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
+extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
+
+extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
+
+extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
+
+
+/* The personality routine is the function in the C++ (or other language)
+   runtime library which serves as an interface between the system unwind
+   library and language-specific exception handling semantics.  It is
+   specific to the code fragment described by an unwind info block, and
+   it is always referenced via the pointer in the unwind info block, and
+   hence it has no ABI-specified name. 
+
+   Note that this implies that two different C++ implementations can
+   use different names, and have different contents in the language
+   specific data area.  Moreover, that the language specific data 
+   area contains no version info because name of the function invoked
+   provides more effective versioning by detecting at link time the
+   lack of code to handle the different data format.  */
+   
+typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
+     (int, _Unwind_Action, _Unwind_Exception_Class,
+      struct _Unwind_Exception *, struct _Unwind_Context *);
+
+/* @@@ The following alternate entry points are for setjmp/longjmp
+   based unwinding.  */
+
+struct SjLj_Function_Context;
+extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
+extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
+
+extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException
+     (struct _Unwind_Exception *);
+extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind
+     (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *);
+
+/* @@@ The following provide access to the base addresses for text
+   and data-relative addressing in the LDSA.  In order to stay link
+   compatible with the standard ABI for IA-64, we inline these.  */
+
+#ifdef __ia64__
+#include <stdlib.h>
+
+static inline _Unwind_Ptr
+_Unwind_GetDataRelBase (struct _Unwind_Context *_C)
+{
+  /* The GP is stored in R1.  */
+  return _Unwind_GetGR (_C, 1);
+}
+
+static inline _Unwind_Ptr
+_Unwind_GetTextRelBase (struct _Unwind_Context *_C)
+{
+  abort ();
+  return 0;
+}
+#else
+extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *);
+extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
--- libc/sysdeps/hppa/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/hppa/gccframe.h	Sat Aug  4 15:57:33 2001
@@ -0,0 +1,23 @@
+/* Definition of object in frame unwind info.  hppa 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Note: For hppa64 this is 61 */
+#define DWARF_FRAME_REGISTERS 89
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/i386/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/i386/gccframe.h	Mon Aug  6 04:10:49 2001
@@ -0,0 +1,28 @@
+/* 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define DWARF_FRAME_REGISTERS 17
+
+#define CRT_GET_RFIB_DATA(BASE)		\
+  {					\
+    register void *__ebx __asm__("ebx");\
+    BASE = __ebx;			\
+  }
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/m68k/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/m68k/gccframe.h	Sat Aug  4 16:05:41 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  m68k 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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/mach/hurd/i386/Versions.jj	Mon Jun 26 04:18:48 2000
+++ libc/sysdeps/mach/hurd/i386/Versions	Mon Aug  6 05:26:07 2001
@@ -2,7 +2,6 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
   }
 }
--- libc/sysdeps/mach/hurd/i386/Makefile.jj	Wed Jun  6 10:05:41 2001
+++ libc/sysdeps/mach/hurd/i386/Makefile	Mon Aug  6 05:38:05 2001
@@ -7,3 +7,11 @@ $(objpfx)crt0.o: $(objpfx)static-start.o
 	$(link-relocatable)
 
 endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
--- libc/sysdeps/mips/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/mips/gccframe.h	Sat Aug  4 16:05:57 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  mips 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/powerpc/gccframe.h	Sat Aug  4 16:06:04 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  powerpc 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/s390/gccframe.h	Sat Aug  4 16:00:55 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  s390 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define FIRST_PSEUDO_REGISTER 34
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/sh/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/sh/gccframe.h	Sat Aug  4 16:02:12 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  sh 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define DWARF_FRAME_REGISTERS 49
+
+#include <sysdeps/generic/gccframe.h>
--- libc/sysdeps/sparc/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/sparc/gccframe.h	Sat Aug  4 16:06:51 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  sparc 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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/arm/Versions.jj	Sat Aug 19 13:10:40 2000
+++ libc/sysdeps/unix/sysv/linux/arm/Versions	Mon Aug  6 05:26:53 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
   }
   GLIBC_2.1 {
     ioperm; iopl;
--- libc/sysdeps/unix/sysv/linux/arm/Makefile.jj	Fri Mar 16 13:40:07 2001
+++ libc/sysdeps/unix/sysv/linux/arm/Makefile	Mon Aug  6 05:37:12 2001
@@ -19,4 +19,10 @@ 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))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
 endif
--- libc/sysdeps/unix/sysv/linux/alpha/Versions.jj	Fri Feb 16 03:44:54 2001
+++ libc/sysdeps/unix/sysv/linux/alpha/Versions	Mon Aug  6 05:27:48 2001
@@ -6,8 +6,7 @@ libc {
 
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
 
     # b*
     bus_base; bus_base_sparse;
--- libc/sysdeps/unix/sysv/linux/alpha/Makefile.jj	Fri Nov 17 19:20:14 2000
+++ libc/sysdeps/unix/sysv/linux/alpha/Makefile	Mon Aug  6 05:37:12 2001
@@ -23,3 +23,11 @@ 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))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/i386/Versions.jj	Sat Aug 19 13:10:41 2000
+++ libc/sysdeps/unix/sysv/linux/i386/Versions	Mon Aug  6 05:28:00 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
 
     ioperm; iopl;
 
--- libc/sysdeps/unix/sysv/linux/i386/Makefile.jj	Wed Jun  6 10:06:07 2001
+++ libc/sysdeps/unix/sysv/linux/i386/Makefile	Mon Aug  6 05:37:12 2001
@@ -12,6 +12,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))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
 endif
 
 ifeq ($(subdir),resource)
--- libc/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c.jj	Mon Aug  6 05:04:26 2001
+++ libc/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c	Mon Aug  6 05:06:33 2001
@@ -0,0 +1 @@
+/* Linux/ia64 does not need unwind table registry. */
--- libc/sysdeps/unix/sysv/linux/m68k/Versions.jj	Mon Oct 16 16:21:16 2000
+++ libc/sysdeps/unix/sysv/linux/m68k/Versions	Mon Aug  6 05:28:13 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
 
     # c*
     cacheflush;
--- libc/sysdeps/unix/sysv/linux/m68k/Makefile.jj	Mon Oct 16 16:21:16 2000
+++ libc/sysdeps/unix/sysv/linux/m68k/Makefile	Mon Aug  6 05:37:12 2001
@@ -10,6 +10,12 @@ endif
 ifeq ($(subdir),elf)
 sysdep-others += lddlibc4
 install-bin += lddlibc4
+
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
 endif
 
 ifeq ($(subdir),resource)
--- libc/sysdeps/unix/sysv/linux/mips/Versions.jj	Mon Jul 31 16:42:41 2000
+++ libc/sysdeps/unix/sysv/linux/mips/Versions	Mon Aug  6 05:28:25 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
 
     # Needed by gcc:
     _flush_cache;
--- libc/sysdeps/unix/sysv/linux/mips/Makefile.jj	Mon Sep 11 08:46:31 2000
+++ libc/sysdeps/unix/sysv/linux/mips/Makefile	Mon Aug  6 05:37:12 2001
@@ -9,3 +9,11 @@ sysdep_routines += cachectl cacheflush s
 
 sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h
 endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/powerpc/Versions.jj	Sat Aug 19 13:10:44 2000
+++ libc/sysdeps/unix/sysv/linux/powerpc/Versions	Mon Aug  6 05:28:35 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
   }
   GLIBC_2.2 {
     # functions used in other libraries
--- libc/sysdeps/unix/sysv/linux/powerpc/Makefile.jj	Wed Jun  6 10:06:16 2001
+++ libc/sysdeps/unix/sysv/linux/powerpc/Makefile	Mon Aug  6 05:37:12 2001
@@ -6,3 +6,11 @@ endif
 ifeq ($(subdir),resource)
 sysdep_routines += oldgetrlimit64
 endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/s390/s390-32/Versions.jj	Fri Mar 16 13:40:11 2001
+++ libc/sysdeps/unix/sysv/linux/s390/s390-32/Versions	Mon Aug  6 05:28:50 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
   }
   GLIBC_2.2 {
     # functions used in other libraries
--- libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile.jj	Wed Jun  6 10:06:17 2001
+++ libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile	Mon Aug  6 05:37:12 2001
@@ -6,3 +6,11 @@ endif
 ifeq ($(subdir),resource)
 sysdep_routines += oldgetrlimit64
 endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/sparc/sparc32/Versions.jj	Sat Aug 19 13:10:46 2000
+++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/Versions	Mon Aug  6 05:29:01 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
   }
   GLIBC_2.2 {
     # functions used in other libraries
--- libc/sysdeps/unix/sysv/linux/sparc/sparc64/Versions.jj	Fri Feb 16 03:44:54 2001
+++ libc/sysdeps/unix/sysv/linux/sparc/sparc64/Versions	Mon Aug  6 05:29:11 2001
@@ -2,8 +2,7 @@ libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc
     __register_frame; __register_frame_table; __deregister_frame;
-    __register_frame_info; __deregister_frame_info; __frame_state_for;
-    __register_frame_info_table;
+    __frame_state_for; __register_frame_info_table;
   }
   GLIBC_2.2.2 {
     # w*
--- libc/sysdeps/unix/sysv/linux/sparc/Makefile.jj	Thu Nov  9 16:54:47 2000
+++ libc/sysdeps/unix/sysv/linux/sparc/Makefile	Mon Aug  6 05:37:12 2001
@@ -42,3 +42,11 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%.
 	mv -f $(@:.h=.d)-t2 $(@:.h=.d)
 
 endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
--- libc/sysdeps/unix/sysv/linux/configure.in.jj	Mon Jul  9 15:42:57 2001
+++ libc/sysdeps/unix/sysv/linux/configure.in	Mon Aug  6 05:13:06 2001
@@ -44,6 +44,7 @@ case "$machine" in
     ;;
   ia64*)
     arch_minimum_kernel=2.4.0
+    libc_cv_gcc_unwind_find_fde=no
     ;;
   hppa*)
     arch_minimum_kernel=2.3.99
--- libc/sysdeps/unix/sysv/linux/configure.jj	Mon Jul  9 15:42:57 2001
+++ libc/sysdeps/unix/sysv/linux/configure	Mon Aug  6 05:13:40 2001
@@ -57,6 +57,7 @@ case "$machine" in
     ;;
   ia64*)
     arch_minimum_kernel=2.4.0
+    libc_cv_gcc_unwind_find_fde=no
     ;;
   hppa*)
     arch_minimum_kernel=2.3.99
--- libc/sysdeps/vax/gccframe.h.jj	Sat Aug  4 15:40:57 2001
+++ libc/sysdeps/vax/gccframe.h	Sat Aug  4 16:03:30 2001
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info.  vax 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define DWARF_FRAME_REGISTERS 16
+
+#include <sysdeps/generic/gccframe.h>
--- libc/Versions.def.jj	Sat Aug  4 15:00:20 2001
+++ libc/Versions.def	Mon Aug  6 05:16:58 2001
@@ -16,6 +16,9 @@ libc {
 %ifdef USE_IN_LIBIO
   HURD_CTHREADS_0.3
 %endif
+%ifdef EXPORT_UNWIND_FIND_FDE
+  GCC_3.0
+%endif
 }
 libcrypt {
   GLIBC_2.0
--- libc/configure.jj	Sat Aug  4 14:47:21 2001
+++ libc/configure	Mon Aug  6 06:47:15 2001
@@ -2167,10 +2167,25 @@ if test "$ld_library_path_setting" != "o
 *** and run configure again." 1>&2; exit 1; }
 fi
 
+echo $ac_n "checking whether GCC supports -static-libgcc""... $ac_c" 1>&6
+echo "configure:2172: checking whether GCC supports -static-libgcc" >&5
+if eval "test \"`echo '$''{'libc_cv_gcc_static_libgcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if $CC -v -static-libgcc 2>&1 | grep -q 'unrecognized option.*static-libgcc'; then
+  libc_cv_gcc_static_libgcc=
+else
+  libc_cv_gcc_static_libgcc=-static-libgcc
+fi
+fi
+
+echo "$ac_t""$libc_cv_gcc_static_libgcc" 1>&6
+
+
 # Extract the first word of "bash", so it can be a program name with args.
 set dummy bash; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2174: checking for $ac_word" >&5
+echo "configure:2189: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2216,7 +2231,7 @@ if test "$BASH" = no; then
   # Extract the first word of "ksh", so it can be a program name with args.
 set dummy ksh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2220: checking for $ac_word" >&5
+echo "configure:2235: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2266,7 +2281,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2270: checking for $ac_word" >&5
+echo "configure:2285: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2298,7 +2313,7 @@ done
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2302: checking for $ac_word" >&5
+echo "configure:2317: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2338,7 +2353,7 @@ fi
 # Extract the first word of "install-info", so it can be a program name with args.
 set dummy install-info; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2342: checking for $ac_word" >&5
+echo "configure:2357: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_INSTALL_INFO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2373,7 +2388,7 @@ fi
 
 if test "$INSTALL_INFO" != "no"; then
 echo $ac_n "checking for old Debian install-info""... $ac_c" 1>&6
-echo "configure:2377: checking for old Debian install-info" >&5
+echo "configure:2392: checking for old Debian install-info" >&5
 if eval "test \"`echo '$''{'libc_cv_old_debian_install_info'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2408,7 +2423,7 @@ fi
 # Extract the first word of "bison", so it can be a program name with args.
 set dummy bison; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2412: checking for $ac_word" >&5
+echo "configure:2427: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BISON'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2443,7 +2458,7 @@ fi
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:2447: checking for signed size_t type" >&5
+echo "configure:2462: checking for signed size_t type" >&5
 if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2467,12 +2482,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:2471: checking for libc-friendly stddef.h" >&5
+echo "configure:2486: checking for libc-friendly stddef.h" >&5
 if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2476 "configure"
+#line 2491 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -2487,7 +2502,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:2491: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2506: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -2506,7 +2521,7 @@ override stddef.h = # The installed <std
 fi
 
 echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:2510: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:2525: checking whether we need to use -P to assemble .S files" >&5
 if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2529,7 +2544,7 @@ asm-CPPFLAGS = -P # The assembler can't 
 fi
 
 echo $ac_n "checking whether .text pseudo-op must be used""... $ac_c" 1>&6
-echo "configure:2533: checking whether .text pseudo-op must be used" >&5
+echo "configure:2548: checking whether .text pseudo-op must be used" >&5
 if eval "test \"`echo '$''{'libc_cv_dot_text'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2550,7 +2565,7 @@ else
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:2554: checking for assembler global-symbol directive" >&5
+echo "configure:2569: checking for assembler global-symbol directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2580,7 +2595,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:2584: checking for .set assembler directive" >&5
+echo "configure:2599: checking for .set assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2623,7 +2638,7 @@ EOF
 esac
 
 echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:2627: checking for .symver assembler directive" >&5
+echo "configure:2642: checking for .symver assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2642,7 +2657,7 @@ fi
 
 echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
 echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
-echo "configure:2646: checking for ld --version-script" >&5
+echo "configure:2661: checking for ld --version-script" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2665,7 +2680,7 @@ EOF
     if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
 					-nostartfiles -nostdlib
 					-Wl,--version-script,conftest.map
-		       1>&5'; { (eval echo configure:2669: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+		       1>&5'; { (eval echo configure:2684: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
     then
       libc_cv_ld_version_script_option=yes
     else
@@ -2704,7 +2719,7 @@ if test $elf = yes && test $shared != no
 fi
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:2708: checking for .previous assembler directive" >&5
+echo "configure:2723: checking for .previous assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2712,7 +2727,7 @@ else
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2716: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2731: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -2728,7 +2743,7 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:2732: checking for .popsection assembler directive" >&5
+echo "configure:2747: checking for .popsection assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2736,7 +2751,7 @@ else
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -2753,7 +2768,7 @@ EOF
     fi
   fi
   echo $ac_n "checking for .protected and .hidden assembler directive""... $ac_c" 1>&6
-echo "configure:2757: checking for .protected and .hidden assembler directive" >&5
+echo "configure:2772: checking for .protected and .hidden assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_protected_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2763,7 +2778,7 @@ foo:
 .hidden bar
 bar:
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2767: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2782: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_protected_directive=yes
   else
     libc_cv_asm_protected_directive=no
@@ -2775,14 +2790,14 @@ echo "$ac_t""$libc_cv_asm_protected_dire
   
 
   echo $ac_n "checking for -z nodelete option""... $ac_c" 1>&6
-echo "configure:2779: checking for -z nodelete option" >&5
+echo "configure:2794: checking for -z nodelete option" >&5
 if eval "test \"`echo '$''{'libc_cv_z_nodelete'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     cat > conftest.c <<EOF
 int _start (void) { return 42; }
 EOF
-  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,--enable-new-dtags,-z,nodelete 1>&5'; { (eval echo configure:2786: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
+  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,--enable-new-dtags,-z,nodelete 1>&5'; { (eval echo configure:2801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
   then
     libc_cv_z_nodelete=yes
   else
@@ -2795,14 +2810,14 @@ echo "$ac_t""$libc_cv_z_nodelete" 1>&6
   
 
   echo $ac_n "checking for -z nodlopen option""... $ac_c" 1>&6
-echo "configure:2799: checking for -z nodlopen option" >&5
+echo "configure:2814: checking for -z nodlopen option" >&5
 if eval "test \"`echo '$''{'libc_cv_z_nodlopen'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     cat > conftest.c <<EOF
 int _start (void) { return 42; }
 EOF
-  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,--enable-new-dtags,-z,nodlopen 1>&5'; { (eval echo configure:2806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
+  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,--enable-new-dtags,-z,nodlopen 1>&5'; { (eval echo configure:2821: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
   then
     libc_cv_z_nodlopen=yes
   else
@@ -2815,14 +2830,14 @@ echo "$ac_t""$libc_cv_z_nodlopen" 1>&6
   
 
   echo $ac_n "checking for -z initfirst option""... $ac_c" 1>&6
-echo "configure:2819: checking for -z initfirst option" >&5
+echo "configure:2834: checking for -z initfirst option" >&5
 if eval "test \"`echo '$''{'libc_cv_z_initfirst'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     cat > conftest.c <<EOF
 int _start (void) { return 42; }
 EOF
-  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,--enable-new-dtags,-z,initfirst 1>&5'; { (eval echo configure:2826: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
+  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,--enable-new-dtags,-z,initfirst 1>&5'; { (eval echo configure:2841: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
   then
     libc_cv_z_initfirst=yes
   else
@@ -2835,14 +2850,14 @@ echo "$ac_t""$libc_cv_z_initfirst" 1>&6
   
 
   echo $ac_n "checking for -Bgroup option""... $ac_c" 1>&6
-echo "configure:2839: checking for -Bgroup option" >&5
+echo "configure:2854: checking for -Bgroup option" >&5
 if eval "test \"`echo '$''{'libc_cv_Bgroup'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     cat > conftest.c <<EOF
 int _start (void) { return 42; }
 EOF
-  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,-Bgroup -nostdlib 1>&5'; { (eval echo configure:2846: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
+  if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,-Bgroup -nostdlib 1>&5'; { (eval echo configure:2861: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
   then
     libc_cv_Bgroup=yes
   else
@@ -2857,12 +2872,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:2861: checking for .init and .fini sections" >&5
+echo "configure:2876: checking for .init and .fini sections" >&5
 if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2866 "configure"
+#line 2881 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2871,7 +2886,7 @@ asm (".section .init");
 				    asm ("${libc_cv_dot_text}");
 ; return 0; }
 EOF
-if { (eval echo configure:2875: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -2894,7 +2909,7 @@ fi
 
 if test $elf = yes -a $gnu_ld = yes; then
   echo $ac_n "checking whether cc puts quotes around section names""... $ac_c" 1>&6
-echo "configure:2898: checking whether cc puts quotes around section names" >&5
+echo "configure:2913: checking whether cc puts quotes around section names" >&5
 if eval "test \"`echo '$''{'libc_cv_have_section_quotes'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2931,19 +2946,19 @@ if test $elf = yes; then
 else
   if test $ac_cv_prog_cc_works = yes; then
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2935: checking for _ prefix on C symbol names" >&5
+echo "configure:2950: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2940 "configure"
+#line 2955 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:2947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -2958,17 +2973,17 @@ fi
 echo "$ac_t""$libc_cv_asm_underscores" 1>&6
   else
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2962: checking for _ prefix on C symbol names" >&5
+echo "configure:2977: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2967 "configure"
+#line 2982 "configure"
 #include "confdefs.h"
 void underscore_test(void) {
 return; }
 EOF
-if { (eval echo configure:2972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2987: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   if grep _underscore_test conftest* >/dev/null; then
     rm -f conftest*
     libc_cv_asm_underscores=yes
@@ -3000,7 +3015,7 @@ if test $elf = yes; then
 fi
 
 echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:3004: checking for assembler .weak directive" >&5
+echo "configure:3019: checking for assembler .weak directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3023,7 +3038,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive
 
 if test $libc_cv_asm_weak_directive = no; then
   echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:3027: checking for assembler .weakext directive" >&5
+echo "configure:3042: checking for assembler .weakext directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3070,14 +3085,14 @@ EOF
     ;;
   hppa*linux*)
   echo $ac_n "checking for assembler line separator""... $ac_c" 1>&6
-echo "configure:3074: checking for assembler line separator" >&5
+echo "configure:3089: checking for assembler line separator" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_line_sep'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     cat > conftest.s <<EOF
  nop ; is_old_puffin
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:3081: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:3096: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_line_sep='!'
   else
     if test -z "$enable_hacker_mode"; then
@@ -3099,7 +3114,7 @@ EOF
 esac
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:3103: checking for ld --no-whole-archive" >&5
+echo "configure:3118: checking for ld --no-whole-archive" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3110,7 +3125,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:3114: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:3129: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_ld_no_whole_archive=yes
 else
   libc_cv_ld_no_whole_archive=no
@@ -3124,7 +3139,7 @@ if test $libc_cv_ld_no_whole_archive = y
 fi
 
 echo $ac_n "checking for gcc -fexceptions""... $ac_c" 1>&6
-echo "configure:3128: checking for gcc -fexceptions" >&5
+echo "configure:3143: checking for gcc -fexceptions" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_exceptions'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3135,7 +3150,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fexceptions
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:3139: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:3154: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_exceptions=yes
 else
   libc_cv_gcc_exceptions=no
@@ -3150,14 +3165,14 @@ fi
 
 if test "$base_machine" = alpha ; then
 echo $ac_n "checking for function ..ng prefix""... $ac_c" 1>&6
-echo "configure:3154: checking for function ..ng prefix" >&5
+echo "configure:3169: checking for function ..ng prefix" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_alpha_ng_prefix'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<\EOF
 foo () { }
 EOF
-if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'; { (eval echo configure:3161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'; { (eval echo configure:3176: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
 then
   libc_cv_gcc_alpha_ng_prefix=yes
 else
@@ -3184,19 +3199,19 @@ if test "$host_cpu" = powerpc ; then
 # Check for a bug present in at least versions 2.8.x of GCC
 # and versions 1.0.x of EGCS.
 echo $ac_n "checking whether clobbering cr0 causes problems""... $ac_c" 1>&6
-echo "configure:3188: checking whether clobbering cr0 causes problems" >&5
+echo "configure:3203: checking whether clobbering cr0 causes problems" >&5
 if eval "test \"`echo '$''{'libc_cv_c_asmcr0_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3193 "configure"
+#line 3208 "configure"
 #include "confdefs.h"
 int tester(int x) { asm ("" : : : "cc"); return x & 123; }
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:3200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_c_asmcr0_bug='no'
 else
@@ -3218,12 +3233,12 @@ fi
 fi
 
 echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:3222: checking for DWARF2 unwind info support" >&5
+echo "configure:3237: checking for DWARF2 unwind info support" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 3227 "configure"
+#line 3242 "configure"
 static char __EH_FRAME_BEGIN__;
 _start ()
 {
@@ -3250,7 +3265,7 @@ __bzero () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame_info
 			    -nostdlib -nostartfiles
-			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3254: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_dwarf2_unwind_info=static
 else
   libc_cv_gcc_dwarf2_unwind_info=no
@@ -3258,7 +3273,7 @@ fi
 if test $libc_cv_gcc_dwarf2_unwind_info = no; then
   if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame
 			      -nostdlib -nostartfiles
-			      -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3262: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			      -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3277: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_gcc_dwarf2_unwind_info=yes
   else
     libc_cv_gcc_dwarf2_unwind_info=no
@@ -3288,12 +3303,12 @@ EOF
 esac
 
 echo $ac_n "checking for __builtin_expect""... $ac_c" 1>&6
-echo "configure:3292: checking for __builtin_expect" >&5
+echo "configure:3307: checking for __builtin_expect" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_builtin_expect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 3297 "configure"
+#line 3312 "configure"
 int foo (int a)
 {
   a = __builtin_expect (a, 10);
@@ -3301,7 +3316,7 @@ int foo (int a)
 }
 EOF
 if { ac_try='${CC-cc} $CFLAGS -nostdlib -nostartfiles
-			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3305: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3320: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_builtin_expect=yes
 else
   libc_cv_gcc_builtin_expect=no
@@ -3318,12 +3333,12 @@ EOF
 fi
 
 echo $ac_n "checking for local label subtraction""... $ac_c" 1>&6
-echo "configure:3322: checking for local label subtraction" >&5
+echo "configure:3337: checking for local label subtraction" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_subtract_local_labels'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 3327 "configure"
+#line 3342 "configure"
 int foo (int a)
 {
   static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
@@ -3336,7 +3351,7 @@ int foo (int a)
 }
 EOF
 if { ac_try='${CC-cc} $CFLAGS -nostdlib -nostartfiles
-			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3340: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3355: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_subtract_local_labels=yes
 else
   libc_cv_gcc_subtract_local_labels=no
@@ -3353,7 +3368,7 @@ EOF
 fi
 
 echo $ac_n "checking for libgd""... $ac_c" 1>&6
-echo "configure:3357: checking for libgd" >&5
+echo "configure:3372: checking for libgd" >&5
 if test "$with_gd" != "no"; then
   old_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS $libgd_include"
@@ -3362,14 +3377,14 @@ if test "$with_gd" != "no"; then
   old_LIBS="$LIBS"
   LIBS="$LIBS -lgd -lpng -lz -lm"
   cat > conftest.$ac_ext <<EOF
-#line 3366 "configure"
+#line 3381 "configure"
 #include "confdefs.h"
 #include <gd.h>
 int main() {
 gdImagePng (0, 0)
 ; return 0; }
 EOF
-if { (eval echo configure:3373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3388: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   LIBGD=yes
 else
@@ -3389,7 +3404,7 @@ echo "$ac_t""$LIBGD" 1>&6
 
 
 echo $ac_n "checking size of long double""... $ac_c" 1>&6
-echo "configure:3393: checking size of long double" >&5
+echo "configure:3408: checking size of long double" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3397,7 +3412,7 @@ else
   ac_cv_sizeof_long_double=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 3401 "configure"
+#line 3416 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -3408,7 +3423,7 @@ main()
   exit(0);
 }
 EOF
-if { (eval echo configure:3412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_double=`cat conftestval`
 else
@@ -3441,6 +3456,7 @@ libc_link_sources=
 use_ldconfig=no
 ldd_rewrite_script=no
 libc_cv_sysconfdir=$sysconfdir
+libc_cv_gcc_unwind_find_fde=yes
 
 # Iterate over all the sysdep directories we will use, running their
 # configure fragments, and looking for a uname implementation.
@@ -3465,6 +3481,13 @@ for dir in $sysnames; do
   fi
 done
 
+if test x$libc_cv_gcc_unwind_find_fde = xyes; then
+  cat >> confdefs.h <<\EOF
+#define EXPORT_UNWIND_FIND_FDE 1
+EOF
+
+fi
+
 
 
 # If we will use the generic uname implementation, we must figure out what
@@ -3477,7 +3500,7 @@ if test "$uname" = "sysdeps/generic"; th
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:3481: checking OS release for uname" >&5
+echo "configure:3504: checking OS release for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3499,7 +3522,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&
   uname_release="$libc_cv_uname_release"
 
   echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:3503: checking OS version for uname" >&5
+echo "configure:3526: checking OS version for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3521,7 +3544,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:3525: checking stdio selection" >&5
+echo "configure:3548: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -3535,7 +3558,7 @@ echo "$ac_t""$stdio" 1>&6
 # Test for old glibc 2.0.x headers so that they can be removed properly
 # Search only in includedir.
 echo $ac_n "checking for old glibc 2.0.x headers""... $ac_c" 1>&6
-echo "configure:3539: checking for old glibc 2.0.x headers" >&5
+echo "configure:3562: checking for old glibc 2.0.x headers" >&5
 if eval test -f "${includedir}/elfclass.h" -a -f "${includedir}/fcntlbits.h"
 then
   old_glibc_headers=yes
@@ -3596,7 +3619,7 @@ if test $shared = default; then
 fi
 
 echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
-echo "configure:3600: checking whether -fPIC is default" >&5
+echo "configure:3623: checking whether -fPIC is default" >&5
 if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3809,6 +3832,7 @@ s%@RANLIB@%$RANLIB%g
 s%@MIG@%$MIG%g
 s%@CCVERSION@%$CCVERSION%g
 s%@SYSINCLUDES@%$SYSINCLUDES%g
+s%@libc_cv_gcc_static_libgcc@%$libc_cv_gcc_static_libgcc%g
 s%@BASH@%$BASH%g
 s%@libc_cv_have_bash2@%$libc_cv_have_bash2%g
 s%@KSH@%$KSH%g
--- libc/configure.in.jj	Sat Aug  4 14:47:21 2001
+++ libc/configure.in	Mon Aug  6 06:44:21 2001
@@ -692,6 +692,14 @@ AC_MSG_ERROR([
 *** and run configure again.])
 fi
 
+AC_CACHE_CHECK(whether GCC supports -static-libgcc, libc_cv_gcc_static_libgcc, [dnl
+if $CC -v -static-libgcc 2>&1 | grep -q 'unrecognized option.*static-libgcc'; then
+  libc_cv_gcc_static_libgcc=
+else
+  libc_cv_gcc_static_libgcc=-static-libgcc
+fi])
+AC_SUBST(libc_cv_gcc_static_libgcc)
+
 AC_PATH_PROG(BASH, bash, no)
 if test "$BASH" != no &&
    $BASH -c 'test "$BASH_VERSINFO" \
@@ -1412,6 +1420,7 @@ libc_link_sources=
 use_ldconfig=no
 ldd_rewrite_script=no
 libc_cv_sysconfdir=$sysconfdir
+libc_cv_gcc_unwind_find_fde=yes
 
 # Iterate over all the sysdep directories we will use, running their
 # configure fragments, and looking for a uname implementation.
@@ -1437,6 +1446,10 @@ for dir in $sysnames; do
 ]dnl
 done
 
+if test x$libc_cv_gcc_unwind_find_fde = xyes; then
+  AC_DEFINE(EXPORT_UNWIND_FIND_FDE)
+fi
+
 AC_LINK_FILES(`echo $libc_link_sources`, `echo $libc_link_dests`)
 
 # If we will use the generic uname implementation, we must figure out what
--- libc/config.h.in.jj	Sat Aug  4 14:47:21 2001
+++ libc/config.h.in	Mon Aug  6 05:16:31 2001
@@ -44,6 +44,9 @@
 /* Define a symbol_name as a global .symbol_name for ld.  */
 #undef	HAVE_ASM_GLOBAL_DOT_NAME
 
+/* Define if _Unwind_Find_FDE should be exported from glibc.  */
+#undef  EXPORT_UNWIND_FIND_FDE
+
 /* Define to use GNU libio instead of GNU stdio.
    This is defined by configure under --enable-libio.  */
 #undef	USE_IN_LIBIO
--- libc/config.make.in.jj	Mon Jul  9 14:56:55 2001
+++ libc/config.make.in	Mon Aug  6 06:03:28 2001
@@ -46,6 +46,8 @@ need-nopic-initfini = @nopic_initfini@
 with-cvs = @with_cvs@
 old-glibc-headers = @old_glibc_headers@
 
+static-libgcc = @libc_cv_gcc_static_libgcc@
+
 versioning = @VERSIONING@
 oldest-abi = @oldest_abi@
 no-whole-archive = @no_whole_archive@
--- libc/Makerules.jj	Mon Jul  9 15:42:52 2001
+++ libc/Makerules	Mon Aug  6 06:03:10 2001
@@ -400,7 +400,7 @@ endif
 
 ifeq ($(elf),yes)
 define build-shlib-helper
-$(LINK.o) -shared -Wl,-O1 $(sysdep-LDFLAGS) $(config-LDFLAGS) \
+$(LINK.o) -shared $(static-libgcc) -Wl,-O1 $(sysdep-LDFLAGS) $(config-LDFLAGS) \
 	  $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
 	  $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
 	  -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
@@ -460,7 +460,7 @@ $(LINK.o) -Wl,-G -Wl,-bM:SRE -Wl,-bnoent
 endef
 else
 define build-module-helper
-$(LINK.o) -shared $(sysdep-LDFLAGS) $(config-LDFLAGS) \
+$(LINK.o) -shared $(static-libgcc) $(sysdep-LDFLAGS) $(config-LDFLAGS) \
 	  -B$(csu-objpfx) $(load-map-file) \
 	  $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \
 	  -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]