From patchwork Mon Dec 13 12:43:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rainer Orth X-Patchwork-Id: 75327 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 8B229B6EE9 for ; Mon, 13 Dec 2010 23:43:42 +1100 (EST) Received: (qmail 17219 invoked by alias); 13 Dec 2010 12:43:40 -0000 Received: (qmail 17204 invoked by uid 22791); 13 Dec 2010 12:43:38 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, TW_LG, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from snape.CeBiTec.Uni-Bielefeld.DE (HELO smtp-relay.CeBiTec.Uni-Bielefeld.DE) (129.70.160.84) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 13 Dec 2010 12:43:31 +0000 Received: from localhost (localhost.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) by smtp-relay.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTP id 5FEA58EF; Mon, 13 Dec 2010 13:43:28 +0100 (CET) Received: from smtp-relay.CeBiTec.Uni-Bielefeld.DE ([127.0.0.1]) by localhost (malfoy.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) (amavisd-new, port 10024) with LMTP id YClU2u+LFDFW; Mon, 13 Dec 2010 13:43:19 +0100 (CET) Received: from manam.CeBiTec.Uni-Bielefeld.DE (manam.CeBiTec.Uni-Bielefeld.DE [129.70.161.120]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp-relay.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTPS id A74BF8EE; Mon, 13 Dec 2010 13:43:19 +0100 (CET) Received: (from ro@localhost) by manam.CeBiTec.Uni-Bielefeld.DE (8.14.4+Sun/8.14.4/Submit) id oBDChITK007105; Mon, 13 Dec 2010 13:43:18 +0100 (MET) From: Rainer Orth To: "Joseph S. Myers" Cc: gcc-patches@gcc.gnu.org, Jakub Jelinek , Richard Henderson , Ralf Wildenhues Subject: Re: Use dl_iterate_phdr in Solaris 11+ unwinder References: Date: Mon, 13 Dec 2010 13:43:18 +0100 In-Reply-To: (Joseph S. Myers's message of "Mon, 29 Nov 2010 16:48:11 +0000 (UTC)") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (usg-unix-v) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org "Joseph S. Myers" writes: > On Mon, 29 Nov 2010, Rainer Orth wrote: > >> diff -r 523125a49e71 gcc/configure.ac >> --- a/gcc/configure.ac Sat Nov 27 11:35:42 2010 +0100 >> +++ b/gcc/configure.ac Mon Nov 29 11:05:51 2010 +0100 >> @@ -977,6 +977,9 @@ >> gettimeofday mbstowcs wcswidth mmap mincore setlocale \ >> gcc_UNLOCKED_FUNCS) >> >> +# Check for dl_iterate_phdr. >> +AC_CHECK_FUNCS(dl_iterate_phdr, [have_dl_iterate_phdr=yes]) > > This is wrong; it's checking for dl_iterate_phdr on the host rather than > the target. You can't do target link tests at this point, but you can > examine target headers to determine whether they declare something. See > the logic used by some configure tests to determine glibc_header_dir - > since that is actually generic logic for locating target headers and has > nothing to do with glibc, it should probably be refactored into a single > place. Thanks for the hint. I've actually moved the logic up, noticing that the two versions already diverged slightly (the first took $with_headers into account, the second did not), and renamed the variable to target_header_dir to reflect its real meaning. Here's the updated (and close-to-final) version of the patch. It removes all the workarounds for linker bugs, takes your comment into account, and splits the test for dl_iterate_phdr into two: first check for a linker which properly supports .eh_frame_hdr, then check for dl_iterate_phdr in the target libc. HAVE_LD_EH_FRAME_HDR is more generic now: with GNU ld, it means the linker understands --eh-frame-hdr (and needs it to create .eh_frame_hdr sections), with other linkers (Solaris ld only so far) it means the linker can properly create .eh_frame_hdr sections by whatever means (none on Solaris, this happens automatically). I'm now doing away with the separate config/t-sol2-eh since I noticed that unwind-dw2-fde-glibc.c falls back to use the unwind-dw2-fde.c unwinder if dl_iterate_phdr is missing, so the same version of LIB2ADDEH can be used with and without that function. Solaris 11 now works in a largefile environment, so the previous workaround to redefine _FILE_OFFSET_BITS is gone and replaced with a configure check for the fixed header file. With the exception of part of the configure.ac changes, the patch is completely target specific now, and I think it's safe enough to go in even in stage3. I've tested the patch on i386-pc-solaris2.11 with as and gas 2.21 and a fixed Sun linker, and also with gas and gld 2.21, without regressions. To make sure unwind-dw2-fde-glibc.c also works with parts of the dl_iterate_phdr support missing (fixed linker and in this case), I've rebootstrapped with the linker etc. fixes removed, also without regressions. I'm now only waiting for a version of Sun ld on SPARC that creates non-empty search tables in .eh_frame_hdr. Once that is tested as well, I plan to commit the patch (provided there are no issues with the build changes) unless there are strong objections. Thanks. Rainer 2010-01-18 Rainer Orth * configure.ac (gcc_cv_ld_eh_frame_hdr): Only check GNU ld for --eh-frame-hdr. Check for working Sun ld version. (HAVE_LD_EH_FRAME_HDR): Adapt comment. (glibc_header_dir): Set only once. Rename to ... (target_header_dir): ... this. Adapt users. (gcc_cv_target_dl_iterate_frame_hdr): Check on *-*-solaris2*. (TARGET_DL_ITERATE_PHDR): Define if present. * configure: Regenerate. * config.in: Likewise. * config/t-sol2 (LIB2ADDEH, LIB2ADDEHDEP): Define. * crtstuff.c (USE_PT_GNU_EH_FRAME): Define for recent Solaris 11 with linker support and dl_iterate_phdr. * unwind-dw2-fde-glibc.c (USE_PT_GNU_EH_FRAME): Likewise. (_Unwind_IteratePhdrCallback) [PT_SUNW_UNWIND]: Also accept PT_SUNW_UNWIND .eh_frame_hdr sections. [CRT_GET_RFIB_DATA && __i386__ && __sun__ && __svr4__]: Add load_base to data->dbase. [CRT_GET_RFIB_DATA && __x86_64__ && __sun__ && __svr4__]: Handle 64-bit Solaris 10+/x86. * config/sol2-gld.h [TARGET_DL_ITERATE_PHDR && HAVE_LD_EH_FRAME_HDR] (LINK_EH_SPEC): Define. [HAVE_LD_AS_NEEDED] (USE_LD_AS_NEEDED): Define. diff -r 8bf39c5cff42 gcc/config/sol2-gld.h --- a/gcc/config/sol2-gld.h Sat Dec 11 01:54:46 2010 +0100 +++ b/gcc/config/sol2-gld.h Sat Dec 11 23:46:40 2010 +0100 @@ -29,3 +29,17 @@ /* GNU ld needs --export-dynamic to implement -rdynamic. */ #undef RDYNAMIC_SPEC #define RDYNAMIC_SPEC "--export-dynamic" + +/* Solaris 11 build 135+ implements dl_iterate_phdr. */ +#if defined(HAVE_LD_EH_FRAME_HDR) && defined(TARGET_DL_ITERATE_PHDR) + +#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " + +/* Use --as-needed -lgcc_s for eh support, but only with .eh_frame_hdr, + otherwise every executable depends on libgcc_s.so.1 due to + __register_frame_info_bases/__deregister_frame_info_bases references. */ +#ifdef HAVE_LD_AS_NEEDED +#define USE_LD_AS_NEEDED 1 +#endif + +#endif /* HAVE_LD_EH_FRAME && TARGET_DL_ITERATE_PHDR */ diff -r 8bf39c5cff42 gcc/config/t-sol2 --- a/gcc/config/t-sol2 Sat Dec 11 01:54:46 2010 +0100 +++ b/gcc/config/t-sol2 Sat Dec 11 23:46:40 2010 +0100 @@ -28,3 +28,9 @@ tree.h output.h $(TM_H) target.h $(TM_P_H) $(GGC_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/sol2.c + +# Use unwind-dw2-fde-glibc.c. Unless linker support and dl_iterate_phdr +# are present, automatically falls back to unwind-dw2-fde.c. +LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \ + $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c +LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c diff -r 8bf39c5cff42 gcc/configure.ac --- a/gcc/configure.ac Sat Dec 11 01:54:46 2010 +0100 +++ b/gcc/configure.ac Sat Dec 11 23:46:40 2010 +0100 @@ -3979,15 +3979,26 @@ gcc_cv_ld_eh_frame_hdr=yes fi elif test x$gcc_cv_ld != x; then - # Check if linker supports --eh-frame-hdr option - if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then - gcc_cv_ld_eh_frame_hdr=yes - fi + if echo "$ld_ver" | grep GNU > /dev/null; then + # Check if linker supports --eh-frame-hdr option + if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then + gcc_cv_ld_eh_frame_hdr=yes + fi + else + case "$target" in + *-*-solaris2*) + # Sun ld has various bugs in .eh_frame_hdr support before version 1.2247. + if test "$ld_vers_major" -gt 1 || test "$ld_vers_minor" -ge 2247; then + gcc_cv_ld_eh_frame_hdr=yes + fi + ;; + esac + fi fi GCC_TARGET_TEMPLATE([HAVE_LD_EH_FRAME_HDR]) if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then AC_DEFINE(HAVE_LD_EH_FRAME_HDR, 1, -[Define if your linker supports --eh-frame-hdr option.]) +[Define if your linker supports .eh_frame_hdr.]) fi AC_MSG_RESULT($gcc_cv_ld_eh_frame_hdr) @@ -4268,45 +4279,46 @@ [Define to PREFIX/include if cpp should also search that directory.]) fi +if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then + if test "x$with_headers" != x; then + target_header_dir=$with_headers + elif test "x$with_sysroot" = x; then + target_header_dir="${exec_prefix}/${target_noncanonical}/sys-include" + elif test "x$with_build_sysroot" != "x"; then + target_header_dir="${with_build_sysroot}/usr/include" + elif test "x$with_sysroot" = xyes; then + target_header_dir="${exec_prefix}/${target_noncanonical}/sys-root/usr/include" + else + target_header_dir="${with_sysroot}/usr/include" + fi +else + target_header_dir=/usr/include +fi + # Test for stack protector support in target C library. AC_CACHE_CHECK(__stack_chk_fail in target C library, gcc_cv_libc_provides_ssp, [gcc_cv_libc_provides_ssp=no case "$target" in *-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu) - if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then - if test "x$with_headers" != x; then - glibc_header_dir=$with_headers - elif test "x$with_sysroot" = x; then - glibc_header_dir="${exec_prefix}/${target_noncanonical}/sys-include" - elif test "x$with_build_sysroot" != "x"; then - glibc_header_dir="${with_build_sysroot}/usr/include" - elif test "x$with_sysroot" = xyes; then - glibc_header_dir="${exec_prefix}/${target_noncanonical}/sys-root/usr/include" - else - glibc_header_dir="${with_sysroot}/usr/include" - fi - else - glibc_header_dir=/usr/include - fi [# glibc 2.4 and later provides __stack_chk_fail and # either __stack_chk_guard, or TLS access to stack guard canary. - if test -f $glibc_header_dir/features.h \ + if test -f $target_header_dir/features.h \ && $EGREP '^[ ]*#[ ]*define[ ]+__GNU_LIBRARY__[ ]+([1-9][0-9]|[6-9])' \ - $glibc_header_dir/features.h > /dev/null; then + $target_header_dir/features.h > /dev/null; then if $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+([1-9][0-9]|[3-9])' \ - $glibc_header_dir/features.h > /dev/null; then + $target_header_dir/features.h > /dev/null; then gcc_cv_libc_provides_ssp=yes elif $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+2' \ - $glibc_header_dir/features.h > /dev/null \ + $target_header_dir/features.h > /dev/null \ && $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+([1-9][0-9]|[4-9])' \ - $glibc_header_dir/features.h > /dev/null; then + $target_header_dir/features.h > /dev/null; then gcc_cv_libc_provides_ssp=yes elif $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \ - $glibc_header_dir/features.h > /dev/null && \ - test -f $glibc_header_dir/bits/uClibc_config.h && \ + $target_header_dir/features.h > /dev/null && \ + test -f $target_header_dir/bits/uClibc_config.h && \ $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC_HAS_SSP__[ ]+1' \ - $glibc_header_dir/bits/uClibc_config.h > /dev/null; then + $target_header_dir/bits/uClibc_config.h > /dev/null; then gcc_cv_libc_provides_ssp=yes fi fi] @@ -4342,21 +4354,8 @@ [ --with-long-double-128 Use 128-bit long double by default.], gcc_cv_target_ldbl128="$with_long_double_128", [[gcc_cv_target_ldbl128=no - if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then - if test "x$with_sysroot" = x; then - glibc_header_dir="${exec_prefix}/${target_noncanonical}/sys-include" - elif test "x$with_build_sysroot" != "x"; then - glibc_header_dir="${with_build_sysroot}/usr/include" - elif test "x$with_sysroot" = xyes; then - glibc_header_dir="${exec_prefix}/${target_noncanonical}/sys-root/usr/include" - else - glibc_header_dir="${with_sysroot}/usr/include" - fi - else - glibc_header_dir=/usr/include - fi grep '^[ ]*#[ ]*define[ ][ ]*__LONG_DOUBLE_MATH_OPTIONAL' \ - $glibc_header_dir/bits/wordsize.h > /dev/null 2>&1 \ + $target_header_dir/bits/wordsize.h > /dev/null 2>&1 \ && gcc_cv_target_ldbl128=yes ]]) ;; @@ -4366,6 +4365,27 @@ [Define if TFmode long double should be the default]) fi +AC_MSG_CHECKING(dl_iterate_phdr in target C library) +gcc_cv_target_dl_iterate_phdr=unknown +case "$target" in + *-*-solaris2*) + # needs both a dl_iterate_phdr declaration and support for + # compilation with largefile support. + if grep dl_iterate_phdr $target_header_dir/link.h > /dev/null 2>&1 \ + && grep 'large file capable' $target_header_dir/link.h > /dev/null 2>&1; then + gcc_cv_target_dl_iterate_phdr=yes + else + gcc_cv_target_dl_iterate_phdr=no + fi + ;; +esac +GCC_TARGET_TEMPLATE([TARGET_DL_ITERATE_PHDR]) +if test x$gcc_cv_target_dl_iterate_phdr = xyes; then + AC_DEFINE(TARGET_DL_ITERATE_PHDR, 1, +[Define if your target C library provides the `dl_iterate_phdr' function.]) +fi +AC_MSG_RESULT($gcc_cv_target_dl_iterate_phdr) + # Find out what GC implementation we want, or may, use. AC_ARG_WITH(gc, [ --with-gc={page,zone} choose the garbage collection mechanism to use diff -r 8bf39c5cff42 gcc/crtstuff.c --- a/gcc/crtstuff.c Sat Dec 11 01:54:46 2010 +0100 +++ b/gcc/crtstuff.c Sat Dec 11 23:46:40 2010 +0100 @@ -1,7 +1,7 @@ /* Specialized bits of code needed to support construction and destruction of file-scope objects in C++ code. Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@monkeys.com). This file is part of GCC. @@ -90,6 +90,15 @@ #if defined(OBJECT_FORMAT_ELF) \ && !defined(OBJECT_FORMAT_FLAT) \ + && defined(HAVE_LD_EH_FRAME_HDR) && defined(TARGET_DL_ITERATE_PHDR) \ + && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ + && defined(__sun__) && defined(__svr4__) +#include +# define USE_PT_GNU_EH_FRAME +#endif + +#if defined(OBJECT_FORMAT_ELF) \ + && !defined(OBJECT_FORMAT_FLAT) \ && defined(HAVE_LD_EH_FRAME_HDR) \ && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ && defined(__GLIBC__) && __GLIBC__ >= 2 diff -r 8bf39c5cff42 gcc/unwind-dw2-fde-glibc.c --- a/gcc/unwind-dw2-fde-glibc.c Sat Dec 11 01:54:46 2010 +0100 +++ b/gcc/unwind-dw2-fde-glibc.c Sat Dec 11 23:46:40 2010 +0100 @@ -1,4 +1,5 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009, 2010 + Free Software Foundation, Inc. Contributed by Jakub Jelinek . This file is part of GCC. @@ -57,6 +58,12 @@ # define USE_PT_GNU_EH_FRAME #endif +#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \ + && defined(TARGET_DL_ITERATE_PHDR) \ + && defined(__sun__) && defined(__svr4__) +# define USE_PT_GNU_EH_FRAME +#endif + #if defined(USE_PT_GNU_EH_FRAME) #include @@ -256,6 +263,12 @@ } else if (phdr->p_type == PT_GNU_EH_FRAME) p_eh_frame_hdr = phdr; +#ifdef PT_SUNW_UNWIND + /* Sun ld emits PT_SUNW_UNWIND .eh_frame_hdr sections instead of + PT_SUNW_EH_FRAME/PT_GNU_EH_FRAME, so accept them as well. */ + else if (phdr->p_type == PT_SUNW_UNWIND) + p_eh_frame_hdr = phdr; +#endif else if (phdr->p_type == PT_DYNAMIC) p_dynamic = phdr; } @@ -305,13 +318,22 @@ for (; dyn->d_tag != DT_NULL ; dyn++) if (dyn->d_tag == DT_PLTGOT) { - /* On IA-32, _DYNAMIC is writable and GLIBC has relocated it. */ data->dbase = (void *) dyn->d_un.d_ptr; +#if defined __linux__ + /* On IA-32 Linux, _DYNAMIC is writable and GLIBC has + relocated it. */ +#elif defined __sun__ && defined __svr4__ + /* On Solaris 2/x86, we need to do this ourselves. */ + data->dbase += load_base; +#endif break; } } # elif defined __FRV_FDPIC__ && defined __linux__ data->dbase = load_base.got_value; +# elif defined __x86_64__ && defined __sun__ && defined __svr4__ + /* While CRT_GET_RFIB_DATA is also defined for 64-bit Solaris 10+/x86, it + doesn't apply since it uses DW_EH_PE_pcrel encoding. */ # else # error What is DW_EH_PE_datarel base on this platform? # endif