summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-11-16 01:27:24 +0000
committerUlrich Drepper <drepper@redhat.com>2001-11-16 01:27:24 +0000
commit74bd2300b57fdb2540478e8698ef7f9067db792c (patch)
tree5adf4e4f6294bb2c418c211c686f918452420fab
parent4acda75c3da212931811a902e4658e0c681f83f2 (diff)
Update.
2001-10-02 Jakub Jelinek <jakub@redhat.com> H.J. Lu <hjl@gnu.org> * 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. (gcc3): Allow glibc to be compiled with gcc 3.x. * config.h.in (EXPORT_UNWIND_FIND_FDE): Add. * config.make.in (static-libgcc, unwind-find-fde): Add. * Makerules (build-shlib-helper, build-module-helper): Use it. * scripts/versions.awk: Make sure GLIBC_ versions come first. * elf/soinit.c (__libc_global_ctors): Set tbases and dbases if necessary. (_fini): Call __deregister_frame_info_bases if __register_frame_info_bases was used to register. * elf/Versions (__register_frame_info, __deregister_frame_info): Add for GLIBC_2.0. (__register_frame_info_bases, __register_frame_info_table_bases, __deregister_frame_info_bases, _Unwind_Find_FDE): Add for GLIBC_2.2.5. * elf/Makefile (routines): Add unwind-dw2-fde. (shared-only-routines): Add unwind-dw2-fde. * sysdeps/alpha/gccframe.h: New file. * sysdeps/arm/gccframe.h: New file. * sysdeps/generic/framestate.c: New file. * sysdeps/generic/dwarf2.h: New file. * sysdeps/generic/gccframe.h (struct object): Update from gcc 3.0. * sysdeps/generic/unwind-dw2-fde.c: New file. * sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c: New file. * sysdeps/generic/unwind-dw2-fde.h: New file. * sysdeps/generic/unwind-dw2.c: New file. * sysdeps/generic/unwind-pe.h: New file. * sysdeps/generic/unwind.h: New file. * sysdeps/hppa/gccframe.h: New file. * sysdeps/i386/gccframe.h: New file. * sysdeps/m68k/gccframe.h: New file. * sysdeps/mips/gccframe.h: New file. * sysdeps/powerpc/gccframe.h: New file. * sysdeps/s390/gccframe.h: New file. * sysdeps/sh/gccframe.h: New file. * sysdeps/sparc/gccframe.h: New file. * sysdeps/vax/gccframe.h: New file. * sysdeps/unix/sysv/linux/configure.in (libc_cv_gcc_unwind_find_fde): Set on all architectures except ia64. * sysdeps/mach/hurd/configure.in (libc_cv_gcc_unwind_find_fde): Set for i386. * 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. * sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: New file. * sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed: New file. * sysdeps/generic/strnlen.c: New file.
-rw-r--r--ChangeLog72
-rw-r--r--Makerules4
-rw-r--r--config.h.in3
-rw-r--r--config.make.in3
-rwxr-xr-xconfigure207
-rw-r--r--configure.in35
-rw-r--r--elf/Makefile5
-rw-r--r--elf/Versions9
-rw-r--r--elf/soinit.c24
-rw-r--r--localedata/locales/se_NO311
-rw-r--r--sysdeps/alpha/gccframe.h22
-rw-r--r--sysdeps/arm/gccframe.h22
-rw-r--r--sysdeps/generic/dwarf2.h585
-rw-r--r--sysdeps/generic/framestate.c47
-rw-r--r--sysdeps/generic/gccframe.h32
-rw-r--r--sysdeps/generic/unwind-dw2-fde.c1021
-rw-r--r--sysdeps/generic/unwind-dw2-fde.h165
-rw-r--r--sysdeps/generic/unwind-dw2.c1207
-rw-r--r--sysdeps/generic/unwind-pe.h272
-rw-r--r--sysdeps/generic/unwind.h191
-rw-r--r--sysdeps/hppa/gccframe.h23
-rw-r--r--sysdeps/i386/gccframe.h28
-rw-r--r--sysdeps/m68k/gccframe.h22
-rwxr-xr-xsysdeps/mach/hurd/configure8
-rw-r--r--sysdeps/mach/hurd/configure.in8
-rw-r--r--sysdeps/mach/hurd/i386/Makefile7
-rw-r--r--sysdeps/mach/hurd/i386/Versions3
-rw-r--r--sysdeps/mips/gccframe.h22
-rw-r--r--sysdeps/powerpc/gccframe.h22
-rw-r--r--sysdeps/s390/gccframe.h22
-rw-r--r--sysdeps/sh/gccframe.h22
-rw-r--r--sysdeps/sparc/gccframe.h22
-rw-r--r--sysdeps/unix/sysv/linux/alpha/Makefile8
-rw-r--r--sysdeps/unix/sysv/linux/alpha/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/arm/Makefile6
-rw-r--r--sysdeps/unix/sysv/linux/arm/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/configure27
-rw-r--r--sysdeps/unix/sysv/linux/configure.in21
-rw-r--r--sysdeps/unix/sysv/linux/i386/Makefile6
-rw-r--r--sysdeps/unix/sysv/linux/i386/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/Makefile6
-rw-r--r--sysdeps/unix/sysv/linux/m68k/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/mips/Makefile8
-rw-r--r--sysdeps/unix/sysv/linux/mips/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/Makefile8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/Makefile8
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Makefile8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/Versions3
-rw-r--r--sysdeps/vax/gccframe.h22
53 files changed, 4446 insertions, 156 deletions
diff --git a/ChangeLog b/ChangeLog
index 7851b1b87c..239cc91ff6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,69 @@
+2001-10-02 Jakub Jelinek <jakub@redhat.com>
+ H.J. Lu <hjl@gnu.org>
+
+ * 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.
+ (gcc3): Allow glibc to be compiled with gcc 3.x.
+ * config.h.in (EXPORT_UNWIND_FIND_FDE): Add.
+ * config.make.in (static-libgcc, unwind-find-fde): Add.
+ * Makerules (build-shlib-helper, build-module-helper): Use it.
+ * scripts/versions.awk: Make sure GLIBC_ versions come first.
+ * elf/soinit.c (__libc_global_ctors): Set tbases and dbases if
+ necessary.
+ (_fini): Call __deregister_frame_info_bases if
+ __register_frame_info_bases was used to register.
+ * elf/Versions (__register_frame_info, __deregister_frame_info): Add
+ for GLIBC_2.0.
+ (__register_frame_info_bases, __register_frame_info_table_bases,
+ __deregister_frame_info_bases, _Unwind_Find_FDE): Add for GLIBC_2.2.5.
+ * elf/Makefile (routines): Add unwind-dw2-fde.
+ (shared-only-routines): Add unwind-dw2-fde.
+ * sysdeps/alpha/gccframe.h: New file.
+ * sysdeps/arm/gccframe.h: New file.
+ * sysdeps/generic/framestate.c: New file.
+ * sysdeps/generic/dwarf2.h: New file.
+ * sysdeps/generic/gccframe.h (struct object): Update from gcc 3.0.
+ * sysdeps/generic/unwind-dw2-fde.c: New file.
+ * sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c: New file.
+ * sysdeps/generic/unwind-dw2-fde.h: New file.
+ * sysdeps/generic/unwind-dw2.c: New file.
+ * sysdeps/generic/unwind-pe.h: New file.
+ * sysdeps/generic/unwind.h: New file.
+ * sysdeps/hppa/gccframe.h: New file.
+ * sysdeps/i386/gccframe.h: New file.
+ * sysdeps/m68k/gccframe.h: New file.
+ * sysdeps/mips/gccframe.h: New file.
+ * sysdeps/powerpc/gccframe.h: New file.
+ * sysdeps/s390/gccframe.h: New file.
+ * sysdeps/sh/gccframe.h: New file.
+ * sysdeps/sparc/gccframe.h: New file.
+ * sysdeps/vax/gccframe.h: New file.
+ * sysdeps/unix/sysv/linux/configure.in (libc_cv_gcc_unwind_find_fde):
+ Set on all architectures except ia64.
+ * sysdeps/mach/hurd/configure.in (libc_cv_gcc_unwind_find_fde): Set
+ for i386.
+ * 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.
+
2001-11-15 Jeff Law <law@redhat.com>
* posix/regex.c (uintptr_t): Do not provide a definition if the
@@ -798,8 +864,8 @@
2001-09-18 Jakub Jelinek <jakub@redhat.com>
- * sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: New.
- * sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed: New.
+ * sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: New file.
+ * sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed: New file.
* sysdeps/unix/sysv/linux/configure.in: Add ia64 and s390
ldd-rewrite scripts.
@@ -1632,7 +1698,7 @@
2001-08-21 Jakub Jelinek <jakub@redhat.com>
* string/strnlen.c: Remove.
- * sysdeps/generic/strnlen.c: New.
+ * sysdeps/generic/strnlen.c: New file.
* sysdeps/i386/i486/bits/string.h (strnlen): Remove.
2001-08-21 Roland McGrath <roland@frob.com>
diff --git a/Makerules b/Makerules
index 59ca838166..ac1bdb7830 100644
--- a/Makerules
+++ b/Makerules
@@ -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,-bnoentry -Wl,-bexpall \
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)
diff --git a/config.h.in b/config.h.in
index ffeb1f39de..475bd72a38 100644
--- a/config.h.in
+++ b/config.h.in
@@ -48,6 +48,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
diff --git a/config.make.in b/config.make.in
index 625e328bc8..4c382b2f49 100644
--- a/config.make.in
+++ b/config.make.in
@@ -46,6 +46,9 @@ have-Bgroup = @libc_cv_Bgroup@
need-nopic-initfini = @nopic_initfini@
with-cvs = @with_cvs@
old-glibc-headers = @old_glibc_headers@
+unwind-find-fde = @libc_cv_gcc_unwind_find_fde@
+
+static-libgcc = @libc_cv_gcc_static_libgcc@
versioning = @VERSIONING@
oldest-abi = @oldest_abi@
diff --git a/configure b/configure
index 7025017910..a07ca8a882 100755
--- a/configure
+++ b/configure
@@ -2105,27 +2105,6 @@ test -n "$aux_missing" && echo "configure: warning:
CCVERSION=`$CC -v 2>&1 | sed -n 's/gcc version //p'`
-case $CCVERSION in
- 3.*) gcc3=yes;;
-esac
-
-if test x"$gcc3" = xyes; then
- echo "\
-*** This version of GNU libc cannot be compiled by GCC 3.x.
-*** GCC 3.x will generate a library that is binary incompatible to
-*** older and future releases of GNU libc.
-*** You should compile this GNU libc release by an older GCC version
-*** or wait for the next GNU libc release."
- if test $enable_sanity = yes; then
- echo "\
-*** If you really mean to use GCC 3.x, run configure again
-*** using the extra parameter \`--disable-sanity-checks'."
- exit 1
- else
- echo "\
-*** This configuration is not supported by the GNU libc developers."
- fi
-fi
# if using special system headers, find out the compiler's sekrit
# header directory and add that to the list. NOTE: Only does the right
# thing on a system that doesn't need fixincludes. (Not presently a problem.)
@@ -2137,7 +2116,7 @@ fi
# check if ranlib is necessary
echo $ac_n "checking whether ranlib is necessary""... $ac_c" 1>&6
-echo "configure:2141: checking whether ranlib is necessary" >&5
+echo "configure:2120: checking whether ranlib is necessary" >&5
if eval "test \"`echo '$''{'libc_cv_ranlib_necessary'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2171,7 +2150,7 @@ fi
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
echo $ac_n "checking LD_LIBRARY_PATH variable""... $ac_c" 1>&6
-echo "configure:2175: checking LD_LIBRARY_PATH variable" >&5
+echo "configure:2154: checking LD_LIBRARY_PATH variable" >&5
case ${LD_LIBRARY_PATH} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
ld_library_path_setting="contains current directory"
@@ -2188,10 +2167,25 @@ if test "$ld_library_path_setting" != "ok"; then
*** 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:2195: 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
@@ -2237,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:2241: 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
@@ -2287,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:2291: 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
@@ -2319,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:2323: 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
@@ -2359,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:2363: 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
@@ -2394,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:2398: 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
@@ -2429,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:2433: 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
@@ -2464,7 +2458,7 @@ fi
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:2468: 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
@@ -2488,12 +2482,12 @@ EOF
fi
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:2492: 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 2497 "configure"
+#line 2491 "configure"
#include "confdefs.h"
#define __need_size_t
#define __need_wchar_t
@@ -2508,7 +2502,7 @@ size_t size; wchar_t wchar;
if (&size == NULL || &wchar == NULL) abort ();
; return 0; }
EOF
-if { (eval echo configure:2512: \"$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
@@ -2527,7 +2521,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
fi
echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:2531: 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
@@ -2550,7 +2544,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
fi
echo $ac_n "checking whether .text pseudo-op must be used""... $ac_c" 1>&6
-echo "configure:2554: 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
@@ -2571,7 +2565,7 @@ else
fi
echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:2575: 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
@@ -2601,7 +2595,7 @@ EOF
fi
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:2605: 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
@@ -2644,7 +2638,7 @@ EOF
esac
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:2648: 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
@@ -2663,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:2667: 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
@@ -2686,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:2690: \"$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
@@ -2725,7 +2719,7 @@ if test $elf = yes && test $shared != no && test $VERSIONING = no; then
fi
if test $elf = yes; then
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:2729: 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
@@ -2733,7 +2727,7 @@ else
.section foo_section
.previous
EOF
- if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2737: \"$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
@@ -2749,7 +2743,7 @@ EOF
else
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:2753: 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
@@ -2757,7 +2751,7 @@ else
.pushsection foo_section
.popsection
EOF
- if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2761: \"$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
@@ -2774,7 +2768,7 @@ EOF
fi
fi
echo $ac_n "checking for .protected and .hidden assembler directive""... $ac_c" 1>&6
-echo "configure:2778: 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
@@ -2784,7 +2778,7 @@ foo:
.hidden bar
bar:
EOF
- if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2788: \"$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
@@ -2796,14 +2790,14 @@ echo "$ac_t""$libc_cv_asm_protected_directive" 1>&6
echo $ac_n "checking for -z nodelete option""... $ac_c" 1>&6
-echo "configure:2800: 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:2807: \"$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
@@ -2816,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:2820: 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:2827: \"$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
@@ -2836,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:2840: 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:2847: \"$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
@@ -2856,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:2860: 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:2867: \"$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
@@ -2876,14 +2870,14 @@ echo "$ac_t""$libc_cv_Bgroup" 1>&6
echo $ac_n "checking for -z combreloc""... $ac_c" 1>&6
-echo "configure:2880: checking for -z combreloc" >&5
+echo "configure:2874: checking for -z combreloc" >&5
if eval "test \"`echo '$''{'libc_cv_z_combreloc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.c <<EOF
int foo (void) { return 0; }
EOF
- if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,-z,combreloc 1>&5'; { (eval echo configure:2887: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
+ if { ac_try='${CC-cc} -shared -o conftest.so conftest.c -Wl,-z,combreloc 1>&5'; { (eval echo configure:2881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
then
if readelf -S conftest.so | grep '\.rel\(a\|\)\.dyn' > /dev/null; then
libc_cv_z_combreloc=yes
@@ -2908,12 +2902,12 @@ fi
if test $elf != yes; then
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:2912: checking for .init and .fini sections" >&5
+echo "configure:2906: 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 2917 "configure"
+#line 2911 "configure"
#include "confdefs.h"
int main() {
@@ -2922,7 +2916,7 @@ asm (".section .init");
asm ("${libc_cv_dot_text}");
; return 0; }
EOF
-if { (eval echo configure:2926: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2920: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_have_initfini=yes
else
@@ -2945,7 +2939,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:2949: checking whether cc puts quotes around section names" >&5
+echo "configure:2943: 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
@@ -2982,19 +2976,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:2986: checking for _ prefix on C symbol names" >&5
+echo "configure:2980: 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 2991 "configure"
+#line 2985 "configure"
#include "confdefs.h"
asm ("_glibc_foobar:");
int main() {
glibc_foobar ();
; return 0; }
EOF
-if { (eval echo configure:2998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2992: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
libc_cv_asm_underscores=yes
else
@@ -3009,17 +3003,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:3013: checking for _ prefix on C symbol names" >&5
+echo "configure:3007: 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 3018 "configure"
+#line 3012 "configure"
#include "confdefs.h"
void underscore_test(void) {
return; }
EOF
-if { (eval echo configure:3023: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3017: \"$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
@@ -3051,7 +3045,7 @@ if test $elf = yes; then
fi
echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:3055: checking for assembler .weak directive" >&5
+echo "configure:3049: 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
@@ -3074,7 +3068,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
if test $libc_cv_asm_weak_directive = no; then
echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:3078: checking for assembler .weakext directive" >&5
+echo "configure:3072: 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
@@ -3121,14 +3115,14 @@ EOF
;;
hppa*linux*)
echo $ac_n "checking for assembler line separator""... $ac_c" 1>&6
-echo "configure:3125: checking for assembler line separator" >&5
+echo "configure:3119: 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:3132: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:3126: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_asm_line_sep='!'
else
if test -z "$enable_hacker_mode"; then
@@ -3150,7 +3144,7 @@ EOF
esac
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:3154: checking for ld --no-whole-archive" >&5
+echo "configure:3148: 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
@@ -3161,7 +3155,7 @@ __throw () {}
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -Wl,--no-whole-archive
- -o conftest conftest.c 1>&5'; { (eval echo configure:3165: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c 1>&5'; { (eval echo configure:3159: \"$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
@@ -3175,7 +3169,7 @@ if test $libc_cv_ld_no_whole_archive = yes; then
fi
echo $ac_n "checking for gcc -fexceptions""... $ac_c" 1>&6
-echo "configure:3179: checking for gcc -fexceptions" >&5
+echo "configure:3173: 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
@@ -3186,7 +3180,7 @@ __throw () {}
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -fexceptions
- -o conftest conftest.c 1>&5'; { (eval echo configure:3190: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c 1>&5'; { (eval echo configure:3184: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc_exceptions=yes
else
libc_cv_gcc_exceptions=no
@@ -3201,14 +3195,14 @@ fi
if test "$base_machine" = alpha ; then
echo $ac_n "checking for function ..ng prefix""... $ac_c" 1>&6
-echo "configure:3205: checking for function ..ng prefix" >&5
+echo "configure:3199: 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:3212: \"$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:3206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
then
libc_cv_gcc_alpha_ng_prefix=yes
else
@@ -3235,19 +3229,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:3239: checking whether clobbering cr0 causes problems" >&5
+echo "configure:3233: 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 3244 "configure"
+#line 3238 "configure"
#include "confdefs.h"
int tester(int x) { asm ("" : : : "cc"); return x & 123; }
int main() {
; return 0; }
EOF
-if { (eval echo configure:3251: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3245: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_c_asmcr0_bug='no'
else
@@ -3269,12 +3263,12 @@ fi
fi
echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:3273: checking for DWARF2 unwind info support" >&5
+echo "configure:3267: 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 3278 "configure"
+#line 3272 "configure"
static char __EH_FRAME_BEGIN__;
_start ()
{
@@ -3301,7 +3295,7 @@ __bzero () {}
EOF
if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame_info
-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:3299: \"$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
@@ -3309,7 +3303,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:3313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3307: \"$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
@@ -3339,12 +3333,12 @@ EOF
esac
echo $ac_n "checking for __builtin_expect""... $ac_c" 1>&6
-echo "configure:3343: checking for __builtin_expect" >&5
+echo "configure:3337: 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 3348 "configure"
+#line 3342 "configure"
int foo (int a)
{
a = __builtin_expect (a, 10);
@@ -3352,7 +3346,7 @@ int foo (int a)
}
EOF
if { ac_try='${CC-cc} $CFLAGS -nostdlib -nostartfiles
- -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3356: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3350: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc_builtin_expect=yes
else
libc_cv_gcc_builtin_expect=no
@@ -3369,12 +3363,12 @@ EOF
fi
echo $ac_n "checking for local label subtraction""... $ac_c" 1>&6
-echo "configure:3373: checking for local label subtraction" >&5
+echo "configure:3367: 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 3378 "configure"
+#line 3372 "configure"
int foo (int a)
{
static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
@@ -3387,7 +3381,7 @@ int foo (int a)
}
EOF
if { ac_try='${CC-cc} $CFLAGS -nostdlib -nostartfiles
- -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3391: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c -lgcc >&5'; { (eval echo configure:3385: \"$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
@@ -3404,7 +3398,7 @@ EOF
fi
echo $ac_n "checking for libgd""... $ac_c" 1>&6
-echo "configure:3408: checking for libgd" >&5
+echo "configure:3402: checking for libgd" >&5
if test "$with_gd" != "no"; then
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $libgd_include"
@@ -3413,14 +3407,14 @@ if test "$with_gd" != "no"; then
old_LIBS="$LIBS"
LIBS="$LIBS -lgd -lpng -lz -lm"
cat > conftest.$ac_ext <<EOF
-#line 3417 "configure"
+#line 3411 "configure"
#include "confdefs.h"
#include <gd.h>
int main() {
gdImagePng (0, 0)
; return 0; }
EOF
-if { (eval echo configure:3424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3418: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
LIBGD=yes
else
@@ -3440,7 +3434,7 @@ echo "$ac_t""$LIBGD" 1>&6
echo $ac_n "checking size of long double""... $ac_c" 1>&6
-echo "configure:3444: checking size of long double" >&5
+echo "configure:3438: 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
@@ -3448,7 +3442,7 @@ else
ac_cv_sizeof_long_double=0
else
cat > conftest.$ac_ext <<EOF
-#line 3452 "configure"
+#line 3446 "configure"
#include "confdefs.h"
#include <stdio.h>
int main()
@@ -3459,7 +3453,7 @@ int main()
return(0);
}
EOF
-if { (eval echo configure:3463: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3457: \"$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
@@ -3492,6 +3486,7 @@ libc_link_sources=
use_ldconfig=no
ldd_rewrite_script=no
libc_cv_sysconfdir=$sysconfdir
+libc_cv_gcc_unwind_find_fde=no
# Iterate over all the sysdep directories we will use, running their
# configure fragments, and looking for a uname implementation.
@@ -3516,6 +3511,14 @@ 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
@@ -3528,7 +3531,7 @@ if test "$uname" = "sysdeps/generic"; then
fi
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:3532: checking OS release for uname" >&5
+echo "configure:3535: 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
@@ -3550,7 +3553,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
uname_release="$libc_cv_uname_release"
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:3554: checking OS version for uname" >&5
+echo "configure:3557: 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
@@ -3572,7 +3575,7 @@ else
fi
echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:3576: checking stdio selection" >&5
+echo "configure:3579: checking stdio selection" >&5
case $stdio in
libio) cat >> confdefs.h <<\EOF
@@ -3586,7 +3589,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:3590: checking for old glibc 2.0.x headers" >&5
+echo "configure:3593: 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
@@ -3647,7 +3650,7 @@ if test $shared = default; then
fi
echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
-echo "configure:3651: checking whether -fPIC is default" >&5
+echo "configure:3654: checking whether -fPIC is default" >&5
if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3860,6 +3863,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
@@ -3881,6 +3885,7 @@ s%@no_whole_archive@%$no_whole_archive%g
s%@exceptions@%$exceptions%g
s%@LIBGD@%$LIBGD%g
s%@sizeof_long_double@%$sizeof_long_double%g
+s%@libc_cv_gcc_unwind_find_fde@%$libc_cv_gcc_unwind_find_fde%g
s%@uname_sysname@%$uname_sysname%g
s%@uname_release@%$uname_release%g
s%@uname_version@%$uname_version%g
diff --git a/configure.in b/configure.in
index 6cbcf0e046..8f0df5c7c1 100644
--- a/configure.in
+++ b/configure.in
@@ -636,27 +636,6 @@ test -n "$aux_missing" && AC_MSG_WARN([
CCVERSION=`$CC -v 2>&1 | sed -n 's/gcc version //p'`
AC_SUBST(CCVERSION)
-case $CCVERSION in
- 3.*) gcc3=yes;;
-esac
-
-if test x"$gcc3" = xyes; then
- echo "\
-*** This version of GNU libc cannot be compiled by GCC 3.x.
-*** GCC 3.x will generate a library that is binary incompatible to
-*** older and future releases of GNU libc.
-*** You should compile this GNU libc release by an older GCC version
-*** or wait for the next GNU libc release."
- if test $enable_sanity = yes; then
- echo "\
-*** If you really mean to use GCC 3.x, run configure again
-*** using the extra parameter \`--disable-sanity-checks'."
- exit 1
- else
- echo "\
-*** This configuration is not supported by the GNU libc developers."
- fi
-fi
# if using special system headers, find out the compiler's sekrit
# header directory and add that to the list. NOTE: Only does the right
# thing on a system that doesn't need fixincludes. (Not presently a problem.)
@@ -713,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" \
@@ -1459,6 +1446,7 @@ libc_link_sources=
use_ldconfig=no
ldd_rewrite_script=no
libc_cv_sysconfdir=$sysconfdir
+libc_cv_gcc_unwind_find_fde=no
# Iterate over all the sysdep directories we will use, running their
# configure fragments, and looking for a uname implementation.
@@ -1484,6 +1472,11 @@ 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_SUBST(libc_cv_gcc_unwind_find_fde)
+
AC_LINK_FILES(`echo $libc_link_sources`, `echo $libc_link_dests`)
# If we will use the generic uname implementation, we must figure out what
diff --git a/elf/Makefile b/elf/Makefile
index 91d7e3a508..b39034c7bf 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -66,6 +66,11 @@ distribute := $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
include ../Makeconfig
+ifeq ($(unwind-find-fde),yes)
+routines += unwind-dw2-fde
+shared-only-routines = unwind-dw2-fde
+endif
+
before-compile = $(objpfx)trusted-dirs.h
generated := trusted-dirs.h trusted-dirs.st for-renamed/renamed.so
generated-dirs := for-renamed
diff --git a/elf/Versions b/elf/Versions
index 2506d100a6..a0e691c0ac 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -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
+ GLIBC_2.2.5 {
+ __register_frame_info_bases; __deregister_frame_info_bases;
+ __register_frame_info_table_bases; _Unwind_Find_FDE;
+ }
+%endif
}
ld {
diff --git a/elf/soinit.c b/elf/soinit.c
index ff65af4a36..32ed4454b5 100644
--- a/elf/soinit.c
+++ b/elf/soinit.c
@@ -4,6 +4,7 @@
calling those lists of functions. */
#include <libc-internal.h>
+#include <stdlib.h>
#ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
# include <gccframe.h>
@@ -29,7 +30,10 @@ static char __EH_FRAME_BEGIN__[]
= { };
# ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
extern void __register_frame_info (const void *, struct object *);
+extern void __register_frame_info_bases (const void *, struct object *,
+ void *, void *);
extern void __deregister_frame_info (const void *);
+extern void __deregister_frame_info_bases (const void *);
# else
extern void __register_frame (const void *);
extern void __deregister_frame (const void *);
@@ -47,7 +51,23 @@ __libc_global_ctors (void)
# ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
{
static struct object ob;
+# if defined CRT_GET_RFIB_TEXT || defined CRT_GET_RFIB_DATA
+ void *tbase, *dbase;
+
+# ifdef CRT_GET_RFIB_TEXT
+ CRT_GET_RFIB_TEXT (tbase);
+# else
+ tbase = NULL;
+# endif
+# ifdef CRT_GET_RFIB_DATA
+ CRT_GET_RFIB_DATA (dbase);
+# else
+ dbase = NULL;
+# endif
+ __register_frame_info_bases (__EH_FRAME_BEGIN__, &ob, tbase, dbase);
+# else
__register_frame_info (__EH_FRAME_BEGIN__, &ob);
+# endif
}
# else
__register_frame (__EH_FRAME_BEGIN__);
@@ -66,7 +86,11 @@ _fini (void)
run_hooks (__DTOR_LIST__);
#ifdef HAVE_DWARF2_UNWIND_INFO
# ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
+# if defined CRT_GET_RFIB_TEXT || defined CRT_GET_RFIB_DATA
+ __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
+# else
__deregister_frame_info (__EH_FRAME_BEGIN__);
+# endif
# else
__deregister_frame (__EH_FRAME_BEGIN__);
# endif
diff --git a/localedata/locales/se_NO b/localedata/locales/se_NO
new file mode 100644
index 0000000000..2846da9ddd
--- /dev/null
+++ b/localedata/locales/se_NO
@@ -0,0 +1,311 @@
+# $Id$
+comment_char %
+escape_char /
+%
+% Northern Saami Language Locale for Norway
+% Source: http://www.hum.uit.no/a/trond/loc.html
+% Contact: Børre Gaup
+% Email: boerre.gaup@pc.nu
+% Language: se
+% Territory: NO
+% Revision: 0.1
+% Date: 2001-11-03
+% Application: general
+% Users: general
+% Charset: UTF-8
+% Distribution and use is free, also
+% for commercial purposes.
+
+LC_IDENTIFICATION
+title "Northern Saami language locale for Norway"
+source "http://www.hum.uit.no/a/trond/loc.html"
+address ""
+contact "Børre Gaup"
+email "boerre.gaup@pc.nu"
+tel ""
+fax ""
+language "Northern Saami"
+territory "Norway"
+revision "0.1"
+date "2001-11-09"
+
+category se_NO:2000;LC_IDENTIFICATION
+category se_NO:2000;LC_CTYPE
+category se_NO:2000;LC_COLLATE
+category se_NO:2000;LC_TIME
+category se_NO:2000;LC_NUMERIC
+category se_NO:2000;LC_PAPER
+category se_NO:2000;LC_TELEPHONE
+category se_NO:2000;LC_MEASUREMENT
+category se_NO:2000;LC_ADDRESS
+category se_NO:2000;LC_MONETARY
+category se_NO:2000;LC_MESSAGES
+
+END LC_IDENTIFICATION
+
+
+LC_COLLATE
+copy "iso14651_t1"
+
+collating-symbol <aring>
+collating-symbol <atilde>
+collating-symbol <acircumflex>
+collating-symbol <agrave>
+collating-symbol <aacute>
+collating-symbol <noae>
+collating-symbol <svae>
+collating-symbol <ccedilla>
+collating-symbol <ccaron>
+collating-symbol <ezh>
+collating-symbol <ezhcaron>
+collating-symbol <dstroke>
+collating-symbol <eth>
+collating-symbol <fhook>
+collating-symbol <gcaron>
+collating-symbol <gstroke>
+collating-symbol <kcaron>
+collating-symbol <otilde>
+collating-symbol <oe>
+collating-symbol <ssharp>
+collating-symbol <scaron>
+collating-symbol <oumlaut>
+collating-symbol <oslash>
+
+%
+reorder-after <CAP>
+<MIN>
+
+reorder-after <a>
+<agrave>
+<atilde>
+<aacute>
+<acircumflex>
+
+
+reorder-after <c>
+<ccaron>
+<ccedilla>
+<ezh>
+<ezhcaron>
+
+reorder-after <d>
+<dstroke>
+<eth>
+
+reorder-after <f>
+<fhook>
+
+reorder-after <g>
+<gcaron>
+<gstroke>
+
+reorder-after <k>
+<kcaron>
+
+reorder-after <s>
+<ssharp>
+<scaron>
+
+reorder-after <th>
+<noae>
+<oslash>
+<aring>
+<svae>
+<oumlaut>
+
+reorder-after <U0061>
+<U00E0> <agrave>;<GRA>;<MIN>;IGNORE % 201 à
+<U00E1> <aacute>;<ACA>;<MIN>;IGNORE % 200 á
+<U00E2> <acircumflex>;<CIR>;<MIN>;IGNORE % 202 â
+<U00E3> <atilde>;<TIL>;<MIN>;IGNORE % 203 ã
+
+reorder-after <U0041>
+<U00C0> <agrave>;<GRA>;<CAP>;IGNORE % 321 À
+<U00C1> <aacute>;<ACA>;<CAP>;IGNORE % 320 Á
+<U00C2> <acircumflex>;<CIR>;<CAP>;IGNORE % 322 Â
+<U00C3> <atilde>;<TIL>;<CAP>;IGNORE % 323 Ã
+
+reorder-after <U0063>
+<U00E7> <ccedilla>;<CDI>;<MIN>;IGNORE % 212 ç
+<U010D> <ccaron>;<CAR>;<MIN>;IGNORE % 215 <c<>
+
+reorder-after <U0043>
+<U00C7> <ccedilla>;<CDI>;<CAP>;IGNORE % 332 Ç
+<U010C> <ccaron>;<CAR>;<CAP>;IGNORE % 335 <C<>
+
+reorder-after <U010B>
+<U0292> <ezh>;<BAS>;<MIN>;IGNORE % ezh
+<U01EF> <ezhcaron>;<CAR>;<MIN>;IGNORE % ezh caron
+
+reorder-after <U010A>
+<U01B7> <ezh>;<BAS>;<MIN>;IGNORE % EZH
+<U01EE> <ezhcaron>;<CAR>;<CAP>;IGNORE % EZH caron
+
+reorder-after <U0064>
+<U00F0> <eth>;<PCL>;<MIN>;IGNORE % 218 ð
+<U0111> <dstroke>;<OBL>;<MIN>;IGNORE % 220 <d//>
+
+reorder-after <U0044>
+<U00D0> <eth>;<PCL>;<CAP>;IGNORE % 338 Ð
+<U0110> <dstroke>;<OBL>;<CAP>;IGNORE % 340 <D//>
+
+reorder-after <U0066>
+<U0192> <fhook>;<BAS>;<MIN>;IGNORE % f WITH HOOK
+
+reorder-after <U0123>
+<U01E7> <gcaron>;<CAR>;<MIN>;IGNORE % gcaron
+<U01E5> <gstroke>;<OBL>;<MIN>;IGNORE % gstroke
+
+reorder-after <U0122>
+<U01E6> <gcaron>;<CAR>;<MIN>;IGNORE % Gcaron
+<U01E4> <gstroke>;<OBL>;<MIN>;IGNORE % Gstroke
+
+reorder-after <U0137>
+<U01E9> <kcaron>;<CAR>;<MIN>;IGNORE % kcaron
+reorder-after <U0136>
+<U01E8> <kcaron>;<CAR>;<CAP>;IGNORE % Kcaron
+
+reorder-after <U0053>
+<U00DF> <ssharp>;"<LIG><LIG>";"<MIN><MIN>";IGNORE % ß
+<U0161> <scaron>;<CAR>;<MIN>;IGNORE % 288 <s<>
+<U0160> <scaron>;<CAR>;<CAP>;IGNORE % 405 <S<>
+
+
+reorder-after <U00E3>
+<U00E4> <svae>;<REU>;<MIN>;IGNORE % ä
+<U00E5> <aring>;<RNE>;<MIN>;IGNORE % å
+<U00E6> <noae>;<LIG>;<MIN>;IGNORE % æ
+reorder-after <U00F5>
+<U00F6> <oumlaut>;<REU>;<MIN>;IGNORE % ö
+<U00F8> <oslash>;<OBL>;<MIN>;IGNORE % ø
+
+reorder-after <U00C3>
+<U00C4> <svae>;<REU>;<CAP>;IGNORE % Ä
+<U00C5> <aring>;<RNE>;<CAP>;IGNORE % Å
+<U00C6> <noae>;<LIG>;<CAP>;IGNORE % Æ
+reorder-after <U00D5>
+<U00D6> <oumlaut>;<REU>;<CAP>;IGNORE % Ö
+<U00D8> <oslash>;<OBL>;<CAP>;IGNORE % Ø
+
+% ü/Ü is treated like y/Y but is sorted after the latter
+reorder-after <U00FB>
+<U00FC> <y>;<REU>;<MIN>;IGNORE % ü
+reorder-after <U00DB>
+<U00DC> <y>;<REU>;<CAP>;IGNORE % Ü
+reorder-end
+
+END LC_COLLATE
+
+LC_CTYPE
+copy "i18n"
+END LC_CTYPE
+
+LC_MONETARY
+int_curr_symbol "<U004E><U004F><U004B><U0020>"
+currency_symbol "<U0020><U0072><U0075>"
+mon_decimal_point "<U002C>"
+mon_thousands_sep "<U002E>"
+mon_grouping 3;3
+positive_sign ""
+negative_sign "<U002D>"
+int_frac_digits 2
+frac_digits 2
+p_cs_precedes 1
+p_sep_by_space 0
+n_cs_precedes 1
+n_sep_by_space 0
+p_sign_posn 4
+n_sign_posn 4
+END LC_MONETARY
+
+LC_NUMERIC
+decimal_point "<U002C>"
+thousands_sep "<U002E>"
+grouping 3;3
+END LC_NUMERIC
+
+
+LC_TIME
+abday "<U0073><U006F><U0074><U006E>";"<U0076><U0075><U006F><U0073>";/
+ "<U006D><U0061><U014B>";"<U0067><U0061><U0073><U006B>";/
+ "<U0064><U0075><U006F><U0072>";"<U0062><U0065><U0061><U0072>";/
+ "<U006C><U00E1><U0076>"
+day "<U0073><U006F><U0074><U006E><U0061><U0062><U0065><U0061><U0069><U0076><U0069>";/
+ "<U0076><U0075><U006F><U0073><U0073><U00E1><U0072><U0067><U0061>";/
+ "<U006D><U0061><U014B><U014B><U0065><U0062><U0061><U0072><U0067><U0061>";/
+ "<U0067><U0061><U0073><U006B><U0061><U0076><U0061><U0068><U006B><U006B><U0075>";/
+ "<U0064><U0075><U006F><U0072><U0061><U0073><U0064><U0061><U0074>";/
+ "<U0062><U0065><U0061><U0072><U006A><U0061><U0064><U0061><U0074>";/
+ "<U006C><U00E1><U0076><U0076><U0061><U0072><U0064><U0061><U0074>"
+abmon "<U006F><U0111><U0111><U006A>";"<U0067><U0075><U006F><U0076>";/
+ "<U006E><U006A><U0075><U006B>";"<U0063><U0075><U006F><U014B>";/
+ "<U006D><U0069><U0065><U0073>";"<U0067><U0065><U0061><U0073>";/
+ "<U0073><U0075><U006F><U0069>";"<U0062><U006F><U0072><U0067>";/
+ "<U010D><U0061><U006B><U010D>";"<U0067><U006F><U006C><U0067>";/
+ "<U0073><U006B><U00E1><U0062>";"<U006A><U0075><U006F><U0076>"
+mon "<U006F><U0111><U0111><U0061><U006A><U0061><U0067><U0065><U006D><U00E1><U006E><U0075>";/
+ "<U0067><U0075><U006F><U0076><U0076><U0061><U006D><U00E1><U006E><U0075>";/
+ "<U006E><U006A><U0075><U006B><U010D><U0061><U006D><U00E1><U006E><U0075>";/
+ "<U0063><U0075><U006F><U014B><U006F><U006D><U00E1><U006E><U0075>";/
+ "<U006D><U0069><U0065><U0073><U0073><U0065><U006D><U00E1><U006E><U0075>";/
+ "<U0067><U0065><U0061><U0073><U0073><U0065><U006D><U00E1><U006E><U0075>";/
+ "<U0073><U0075><U006F><U0069><U0064><U006E><U0065><U006D><U00E1><U006E><U0075>";/
+ "<U0062><U006F><U0072><U0067><U0065><U006D><U00E1><U006E><U0075>";/
+ "<U010D><U0061><U006B><U010D><U0061><U006D><U00E1><U006E><U0075>";/
+ "<U0067><U006F><U006C><U0067><U0067><U006F><U0074><U006D><U00E1><U006E><U0075>";/
+ "<U0073><U006B><U00E1><U0062><U006D><U0061><U006D><U00E1><U006E><U0075>";/
+ "<U006A><U0075><U006F><U0076><U006C><U0061><U006D><U00E1><U006E><U0075>"
+% usual date representation
+% Linjen nedenfor er: %a, %b %e b. %Y %T %Z
+% f.eks. bear, geas 14. b. 2001 21:15:11 CEST
+d_t_fmt "<U0025><U0061><U002C><U0020><U0025><U0062><U0020><U0025><U0065><U002E><U0020><U0062><U002E><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
+%Linjen nedenfor er: %Y-%m-%d
+%f.eks 2001-04-26
+d_fmt "<U0025><U0059><U002D><U0025><U006D><U002D><U0025><U0064>"
+t_fmt "<U0025><U0054>"
+am_pm "";""
+t_fmt_ampm ""
+
+% Denne linjen vil gi f.eks.:
+% duorasdat, borgem<U00E1>nu 23. b. 2001 00:47:57 CEST
+date_fmt "<U0025><U0041><U002C><U0020><U0025><U0042><U0020><U0025><U0064><U002E>/
+<U0020><U0062><U002E><U0020><U0025><U0059><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053>/
+<U0020><U0025><U005A>"
+
+% %a %b-%e %H:%M:%S %Z %Y søn jan-31 21:15:11 CET 2001
+END LC_TIME
+
+LC_MESSAGES
+yesexpr "<U005E><U005B><U004A><U006A><U0059><U0079><U005D><U002E><U002A>"
+noexpr "<U005E><U005B><U0049><U0069><U005D><U002E><U002A>"
+END LC_MESSAGES
+
+
+LC_PAPER
+height 297
+width 210
+END LC_PAPER
+
+LC_TELEPHONE
+tel_int_fmt "<U002B><U0025><U0063><U0020><U0025><U006C>"
+tel_dom_fmt "<U0025><U006C>"
+int_select "<U0030><U0030>"
+int_prefix "<U0034><U0037>"
+END LC_TELEPHONE
+
+LC_MEASUREMENT
+measurement 1
+END LC_MEASUREMENT
+
+LC_NAME
+name_fmt "<U0025><U0064><U0025><U0074><U0025><U0067><U0025><U0074>/
+<U0025><U006D><U0025><U0074><U0025><U0066>"
+END LC_NAME
+
+LC_ADDRESS
+postal_fmt "<U0025><U0066><U0025><U004E><U0025><U0061><U0025><U004E>/
+<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
+<U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
+<U004E><U0025><U0025><U007A><U0020><U0025><U0054><U0025>/
+<U004E><U0025><U0063><U0025><U004E>"
+END LC_ADDRESS
diff --git a/sysdeps/alpha/gccframe.h b/sysdeps/alpha/gccframe.h
new file mode 100644
index 0000000000..b67022548f
--- /dev/null
+++ b/sysdeps/alpha/gccframe.h
@@ -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>
diff --git a/sysdeps/arm/gccframe.h b/sysdeps/arm/gccframe.h
new file mode 100644
index 0000000000..ef8df2630e
--- /dev/null
+++ b/sysdeps/arm/gccframe.h
@@ -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>
diff --git a/sysdeps/generic/dwarf2.h b/sysdeps/generic/dwarf2.h
new file mode 100644
index 0000000000..800bda2dc0
--- /dev/null
+++ b/sysdeps/generic/dwarf2.h
@@ -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
diff --git a/sysdeps/generic/framestate.c b/sysdeps/generic/framestate.c
new file mode 100644
index 0000000000..5cb3e6ca85
--- /dev/null
+++ b/sysdeps/generic/framestate.c
@@ -0,0 +1,47 @@
+/* __frame_state_for unwinder helper function wrapper.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
+
+ 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. */
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#define __frame_state_for fallback_frame_state_for
+#include <unwind-dw2.c>
+#undef __frame_state_for
+
+typedef struct frame_state * (*framesf)(void *pc, struct frame_state *);
+struct frame_state *__frame_state_for (void *pc,
+ struct frame_state *frame_state);
+
+struct frame_state *
+__frame_state_for (void *pc, struct frame_state *frame_state)
+{
+ static framesf frame_state_for;
+
+ if (frame_state_for == NULL)
+ {
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL
+ || (frame_state_for
+ = (framesf) __libc_dlsym (handle, "__frame_state_for")) == NULL)
+ frame_state_for = fallback_frame_state_for;
+ }
+
+ return frame_state_for (pc, frame_state);
+}
diff --git a/sysdeps/generic/gccframe.h b/sysdeps/generic/gccframe.h
index c694877605..1df7d713c0 100644
--- a/sysdeps/generic/gccframe.h
+++ b/sysdeps/generic/gccframe.h
@@ -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;
};
diff --git a/sysdeps/generic/unwind-dw2-fde.c b/sysdeps/generic/unwind-dw2-fde.c
new file mode 100644
index 0000000000..b6bbc2bc73
--- /dev/null
+++ b/sysdeps/generic/unwind-dw2-fde.c
@@ -0,0 +1,1021 @@
+/* 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 <shlib-compat.h>
+#endif
+
+#if !defined _LIBC || SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2_5)
+
+#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_recursive (*(m))
+#define __gthread_mutex_unlock(m) __libc_lock_unlock_recursive (*(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;
+}
+
+#endif
diff --git a/sysdeps/generic/unwind-dw2-fde.h b/sysdeps/generic/unwind-dw2-fde.h
new file mode 100644
index 0000000000..83b4470ce5
--- /dev/null
+++ b/sysdeps/generic/unwind-dw2-fde.h
@@ -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 *);
diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c
new file mode 100644
index 0000000000..ac56e7c35c
--- /dev/null
+++ b/sysdeps/generic/unwind-dw2.c
@@ -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 */
diff --git a/sysdeps/generic/unwind-pe.h b/sysdeps/generic/unwind-pe.h
new file mode 100644
index 0000000000..e4a564e3e1
--- /dev/null
+++ b/sysdeps/generic/unwind-pe.h
@@ -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);
+}
diff --git a/sysdeps/generic/unwind.h b/sysdeps/generic/unwind.h
new file mode 100644
index 0000000000..ce43365a31
--- /dev/null
+++ b/sysdeps/generic/unwind.h
@@ -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
diff --git a/sysdeps/hppa/gccframe.h b/sysdeps/hppa/gccframe.h
new file mode 100644
index 0000000000..65e44dfd73
--- /dev/null
+++ b/sysdeps/hppa/gccframe.h
@@ -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>
diff --git a/sysdeps/i386/gccframe.h b/sysdeps/i386/gccframe.h
new file mode 100644
index 0000000000..412fa974de
--- /dev/null
+++ b/sysdeps/i386/gccframe.h
@@ -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>
diff --git a/sysdeps/m68k/gccframe.h b/sysdeps/m68k/gccframe.h
new file mode 100644
index 0000000000..452f53f626
--- /dev/null
+++ b/sysdeps/m68k/gccframe.h
@@ -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>
diff --git a/sysdeps/mach/hurd/configure b/sysdeps/mach/hurd/configure
index fb91f88100..36d0c08b6a 100755
--- a/sysdeps/mach/hurd/configure
+++ b/sysdeps/mach/hurd/configure
@@ -9,3 +9,11 @@ inhibit_glue=yes
if test "x$prefix" != x; then
echo "configure: warning: --prefix= (empty) is required for GNU/Hurd to work normally" 1>&2
fi
+
+case "$machine" in
+ i386*)
+ if test -z "$oldest_abi" || test "$oldest_abi" < "2.2.5"; then
+ libc_cv_gcc_unwind_find_fde=yes
+ fi
+ ;;
+esac
diff --git a/sysdeps/mach/hurd/configure.in b/sysdeps/mach/hurd/configure.in
index 7daa188713..b271d4a810 100644
--- a/sysdeps/mach/hurd/configure.in
+++ b/sysdeps/mach/hurd/configure.in
@@ -11,3 +11,11 @@ inhibit_glue=yes
if test "x$prefix" != x; then
AC_MSG_WARN([--prefix= (empty) is required for GNU/Hurd to work normally])
fi
+
+case "$machine" in
+ i386*)
+ if test -z "$oldest_abi" || test "$oldest_abi" < "2.2.5"; then
+ libc_cv_gcc_unwind_find_fde=yes
+ fi
+ ;;
+esac
diff --git a/sysdeps/mach/hurd/i386/Makefile b/sysdeps/mach/hurd/i386/Makefile
new file mode 100644
index 0000000000..61fac29c9a
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/Makefile
@@ -0,0 +1,7 @@
+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
diff --git a/sysdeps/mach/hurd/i386/Versions b/sysdeps/mach/hurd/i386/Versions
index 2d3061bad5..5731d9e01e 100644
--- a/sysdeps/mach/hurd/i386/Versions
+++ b/sysdeps/mach/hurd/i386/Versions
@@ -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;
}
}
diff --git a/sysdeps/mips/gccframe.h b/sysdeps/mips/gccframe.h
new file mode 100644
index 0000000000..ec9311caca
--- /dev/null
+++ b/sysdeps/mips/gccframe.h
@@ -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>
diff --git a/sysdeps/powerpc/gccframe.h b/sysdeps/powerpc/gccframe.h
new file mode 100644
index 0000000000..d08e80f18e
--- /dev/null
+++ b/sysdeps/powerpc/gccframe.h
@@ -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>
diff --git a/sysdeps/s390/gccframe.h b/sysdeps/s390/gccframe.h
new file mode 100644
index 0000000000..2f624b8f5a
--- /dev/null
+++ b/sysdeps/s390/gccframe.h
@@ -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>
diff --git a/sysdeps/sh/gccframe.h b/sysdeps/sh/gccframe.h
new file mode 100644
index 0000000000..ad392741c4
--- /dev/null
+++ b/sysdeps/sh/gccframe.h
@@ -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>
diff --git a/sysdeps/sparc/gccframe.h b/sysdeps/sparc/gccframe.h
new file mode 100644
index 0000000000..236baab14a
--- /dev/null
+++ b/sysdeps/sparc/gccframe.h
@@ -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>
diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index 62536ae1ae..5c04677086 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -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
diff --git a/sysdeps/unix/sysv/linux/alpha/Versions b/sysdeps/unix/sysv/linux/alpha/Versions
index d89ef6a061..c18816ca6f 100644
--- a/sysdeps/unix/sysv/linux/alpha/Versions
+++ b/sysdeps/unix/sysv/linux/alpha/Versions
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index aeaaa39fce..66a93ba8f3 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -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
diff --git a/sysdeps/unix/sysv/linux/arm/Versions b/sysdeps/unix/sysv/linux/arm/Versions
index aeda9fa5fb..32cb185505 100644
--- a/sysdeps/unix/sysv/linux/arm/Versions
+++ b/sysdeps/unix/sysv/linux/arm/Versions
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/configure b/sysdeps/unix/sysv/linux/configure
index db1666d258..72fa8430ac 100644
--- a/sysdeps/unix/sysv/linux/configure
+++ b/sysdeps/unix/sysv/linux/configure
@@ -54,6 +54,11 @@ fi
case "$machine" in
alpha*)
arch_minimum_kernel=2.1.100
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ i386*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
;;
ia64*)
arch_minimum_kernel=2.4.0
@@ -63,9 +68,19 @@ case "$machine" in
;;
mips*)
arch_minimum_kernel=2.2.15
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ powerpc)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
;;
sh*)
arch_minimum_kernel=2.3.99
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ sparc*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
;;
x86_64*)
arch_minimum_kernel=2.4.0
@@ -91,11 +106,11 @@ fi
if test -n "$minimum_kernel"; then
echo $ac_n "checking for kernel header at least $minimum_kernel""... $ac_c" 1>&6
-echo "configure:95: checking for kernel header at least $minimum_kernel" >&5
+echo "configure:110: checking for kernel header at least $minimum_kernel" >&5
decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`;
cat > conftest.$ac_ext <<EOF
-#line 99 "configure"
+#line 114 "configure"
#include "confdefs.h"
#include <linux/version.h>
#if LINUX_VERSION_CODE < $decnum
@@ -128,6 +143,12 @@ EOF
fi
fi
+# The result of the above test for the use of the FDE code is invalid if
+# the user overrides the decision about the minimum ABI.
+if test "$oldest_abi" != default && test "2.2.4" \< "$oldest_abi"; then
+ libc_cv_gcc_unwind_find_fde=no
+fi
+
if test -n "$sysheaders"; then
CPPFLAGS=$OLD_CPPFLAGS
fi
@@ -219,7 +240,7 @@ if test $host = $build; then
ac_prefix=$ac_default_prefix
fi
echo $ac_n "checking for symlinks in ${ac_prefix}/include""... $ac_c" 1>&6
-echo "configure:223: checking for symlinks in ${ac_prefix}/include" >&5
+echo "configure:244: checking for symlinks in ${ac_prefix}/include" >&5
ac_message=
if test -L ${ac_prefix}/include/net; then
ac_message="$ac_message
diff --git a/sysdeps/unix/sysv/linux/configure.in b/sysdeps/unix/sysv/linux/configure.in
index dfae5a1de3..709d8e913f 100644
--- a/sysdeps/unix/sysv/linux/configure.in
+++ b/sysdeps/unix/sysv/linux/configure.in
@@ -41,6 +41,11 @@ fi
case "$machine" in
alpha*)
arch_minimum_kernel=2.1.100
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ i386*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
;;
ia64*)
arch_minimum_kernel=2.4.0
@@ -50,9 +55,19 @@ case "$machine" in
;;
mips*)
arch_minimum_kernel=2.2.15
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ powerpc)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
;;
sh*)
arch_minimum_kernel=2.3.99
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ sparc*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
;;
x86_64*)
arch_minimum_kernel=2.4.0
@@ -96,6 +111,12 @@ eat flaming death
fi
fi
+# The result of the above test for the use of the FDE code is invalid if
+# the user overrides the decision about the minimum ABI.
+if test "$oldest_abi" != default && test "2.2.4" \< "$oldest_abi"; then
+ libc_cv_gcc_unwind_find_fde=no
+fi
+
if test -n "$sysheaders"; then
CPPFLAGS=$OLD_CPPFLAGS
fi
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index 4a219b89e4..4fc9434074 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/i386/Versions b/sysdeps/unix/sysv/linux/i386/Versions
index 3015c41451..83445a1715 100644
--- a/sysdeps/unix/sysv/linux/i386/Versions
+++ b/sysdeps/unix/sysv/linux/i386/Versions
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c b/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c
new file mode 100644
index 0000000000..15d12abfce
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c
@@ -0,0 +1 @@
+/* Linux/ia64 does not need unwind table registry. */
diff --git a/sysdeps/unix/sysv/linux/m68k/Makefile b/sysdeps/unix/sysv/linux/m68k/Makefile
index 55eeeabe10..83ea370afa 100644
--- a/sysdeps/unix/sysv/linux/m68k/Makefile
+++ b/sysdeps/unix/sysv/linux/m68k/Makefile
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/m68k/Versions b/sysdeps/unix/sysv/linux/m68k/Versions
index 6c650e2ce2..0799bf310e 100644
--- a/sysdeps/unix/sysv/linux/m68k/Versions
+++ b/sysdeps/unix/sysv/linux/m68k/Versions
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile
index 1f9fc2dd03..e46cfef7a5 100644
--- a/sysdeps/unix/sysv/linux/mips/Makefile
+++ b/sysdeps/unix/sysv/linux/mips/Makefile
@@ -9,3 +9,11 @@ sysdep_routines += cachectl cacheflush sysmips _test_and_set
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
diff --git a/sysdeps/unix/sysv/linux/mips/Versions b/sysdeps/unix/sysv/linux/mips/Versions
index d65bf18cb0..f71d9b5d88 100644
--- a/sysdeps/unix/sysv/linux/mips/Versions
+++ b/sysdeps/unix/sysv/linux/mips/Versions
@@ -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;
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index 931611f4db..889df40fe8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -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
diff --git a/sysdeps/unix/sysv/linux/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions
index a2296a968a..d0bf4a89c0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -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
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/Makefile b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
index bac110a28b..75844f455b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
@@ -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
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/Versions b/sysdeps/unix/sysv/linux/s390/s390-32/Versions
index 5a56361b60..3c45a30778 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/Versions
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/Versions
@@ -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
diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile
index 9b46a7ea72..7059a1a31b 100644
--- a/sysdeps/unix/sysv/linux/sparc/Makefile
+++ b/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -42,3 +42,11 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/sys/syscal
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
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Versions b/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
index d7a19f812a..4529e7fe6f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
@@ -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
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
index 65349501fe..cfcc15b119 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
@@ -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*
diff --git a/sysdeps/vax/gccframe.h b/sysdeps/vax/gccframe.h
new file mode 100644
index 0000000000..323d5115d4
--- /dev/null
+++ b/sysdeps/vax/gccframe.h
@@ -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>