This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Support .eh_frame in crt1 x86_64 glibc (PR libc/15407)
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 6 May 2013 19:22:21 +0200
- Subject: [patch] Support .eh_frame in crt1 x86_64 glibc (PR libc/15407)
Hi,
since
[patch] x86_64: CFI unwinding stop in _start
http://sourceware.org/ml/libc-alpha/2012-03/msg00573.html
there is a regression reproducible with gold:
http://sourceware.org/bugzilla/show_bug.cgi?id=15407
as .eh_frame is created before the __EH_FRAME_BEGIN__ marker. Linking order:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o
^^^ .eh_frame is used here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o
^^^ __EH_FRAME_BEGIN__ marker here
Therefore proposing to move the __EH_FRAME_BEGIN__ marker earlier:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin1.o
^^^ __EH_FRAME_BEGIN__ marker here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o
^^^ .eh_frame is used here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o
It is questionable which all targets should this change affect. If find it
a needless + untestable change to split crtbegin.o for very every target.
I have split it for every glibc x86_64 target (I hope) even if the one uses
PT_GNU_EH_FRAME (for which the __EH_FRAME_BEGIN__ marker is not needed),
it does not hurt and it was easier (possible?) that way.
I have split it also for the non-Linux glibc i386 + x86_64 targets as AFAIK
they are also affected the same way by the glibc change.
I had to split also i386 despite the glibc change affects only x86_64. It was
needed for the case of --target=i686-pc-linux-gnu --enable-targets=all where:
gcc/config.gcc:
i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
[...]
if test x$enable_targets = xall; then
tm_file="${tm_file} i386/x86-64.h i386/gnu-user-common.h i386/gnu-user64.h i386/linux-common.h i386/linux64.h"
Here the x86_64 *.h files get included even for the i386 target configuration
so it is no longer possible to make the spec change different for i386.
No regressions for Fedora 19 x86_64 GCC 4.9.0 20130504
and for gcc-4.8.0-3.fc19.{x86_64,i686}.
The x$enable_targets = xall case was tested on Debian 7.0 i386 with:
--enable-languages=c --without-cloog --disable-libquadmath --enable-targets=all
It would be good to test also on some of the *BSD hosts, I will try some from
the GCC Compile Farm if this patch gets approved.
Thanks,
Jan
gcc/
2013-05-06 Jan Kratochvil <jan.kratochvil@redhat.com>
* config/i386/gnu-user-common.h (USE_CRT_BEGIN1)
(GNU_USER_TARGET_BEGIN1_SPEC, STARTFILE_SPEC): New.
* config/i386/linux-common.h (STARTFILE_SPEC): Use also
GNU_USER_TARGET_BEGIN1_SPEC.
libgcc/
2013-05-06 Jan Kratochvil <jan.kratochvil@redhat.com>
* Makefile.in (crtbegin1$(objext), crtbeginS1$(objext))
(crtbeginT1$(objext)): New.
* config.host (i[34567]86-*-linux*, i[34567]86-*-kfreebsd*-gnu)
(i[34567]86-*-knetbsd*-gnu, i[34567]86-*-gnu*)
(i[34567]86-*-kopensolaris*-gnu, x86_64-*-linux*)
(x86_64-*-kfreebsd*-gnu, x86_64-*-knetbsd*-gnu): Add crtbegin1.o,
crtbeginS1.o and crtbeginT1.o.
* crtstuff.c: New block for CRT_BEGIN1. Copy __EH_FRAME_BEGIN__ there
and also move it to the start of CRT_BEGIN block.
diff --git a/gcc/config/i386/gnu-user-common.h b/gcc/config/i386/gnu-user-common.h
index e28483d..7848906 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -45,6 +45,14 @@ along with GCC; see the file COPYING3. If not see
#undef CC1_SPEC
#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC
+#undef USE_CRT_BEGIN1
+#define USE_CRT_BEGIN1
+#define GNU_USER_TARGET_BEGIN1_SPEC \
+ "%{static:crtbeginT1.o%s;shared|pie:crtbeginS1.o%s;:crtbegin1.o%s}"
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC GNU_USER_TARGET_BEGIN1_SPEC " " \
+ GNU_USER_TARGET_STARTFILE_SPEC
+
/* Similar to standard GNU userspace, but adding -ffast-math support. */
#define GNU_USER_TARGET_MATHFILE_SPEC \
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
diff --git a/gcc/config/i386/linux-common.h b/gcc/config/i386/linux-common.h
index 1e8bf6b..a442bb1 100644
--- a/gcc/config/i386/linux-common.h
+++ b/gcc/config/i386/linux-common.h
@@ -44,7 +44,8 @@ along with GCC; see the file COPYING3. If not see
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
- LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, \
+ LINUX_OR_ANDROID_LD (GNU_USER_TARGET_BEGIN1_SPEC " " \
+ GNU_USER_TARGET_STARTFILE_SPEC, \
ANDROID_STARTFILE_SPEC)
#undef ENDFILE_SPEC
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 990cd49..5a8d834 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -953,6 +953,9 @@ ifeq ($(CUSTOM_CRTSTUFF),)
# Compile two additional files that are linked with every program
# linked using GCC on systems using COFF or ELF, for the sake of C++
# constructors.
+crtbegin1$(objext): $(srcdir)/crtstuff.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN1
+
crtbegin$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN
@@ -960,6 +963,9 @@ crtend$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_END
# These are versions of crtbegin and crtend for shared libraries.
+crtbeginS1$(objext): $(srcdir)/crtstuff.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $< -DCRT_BEGIN1 -DCRTSTUFFS_O
+
crtbeginS$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $< -DCRT_BEGIN -DCRTSTUFFS_O
@@ -967,6 +973,9 @@ crtendS$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $< -DCRT_END -DCRTSTUFFS_O
# This is a version of crtbegin for -static links.
+crtbeginT1$(objext): $(srcdir)/crtstuff.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN1 -DCRTSTUFFT_O
+
crtbeginT$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN -DCRTSTUFFT_O
endif
diff --git a/libgcc/config.host b/libgcc/config.host
index 5e0f5ce..e6abdae 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -520,20 +520,24 @@ x86_64-*-openbsd*)
;;
i[34567]86-*-linux*)
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
+ extra_parts="$extra_parts crtbegin1.o crtbeginS1.o crtbeginT1.o"
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
md_unwind_header=i386/linux-unwind.h
;;
i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
+ extra_parts="$extra_parts crtbegin1.o crtbeginS1.o crtbeginT1.o"
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
;;
x86_64-*-linux*)
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
+ extra_parts="$extra_parts crtbegin1.o crtbeginS1.o crtbeginT1.o"
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
md_unwind_header=i386/linux-unwind.h
;;
x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
+ extra_parts="$extra_parts crtbegin1.o crtbeginS1.o crtbeginT1.o"
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
;;
i[34567]86-pc-msdosdjgpp*)
diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c
index 0beda5e..2c434a8 100644
--- a/libgcc/crtstuff.c
+++ b/libgcc/crtstuff.c
@@ -197,7 +197,34 @@ typedef void (*func_ptr) (void);
#endif /* OBJECT_FORMAT_ELF */
-#ifdef CRT_BEGIN
+#ifdef CRT_BEGIN1
+
+#ifndef USE_CRT_BEGIN1
+# error "USE_CRT_BEGIN1 must be defined if CRT_BEGIN1 is in use."
+#endif /* ! USE_CRT_BEGIN1 */
+
+#ifdef USE_EH_FRAME_REGISTRY
+EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
+ __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4),
+ __visibility__ ("hidden")))
+ = { };
+#endif /* USE_EH_FRAME_REGISTRY */
+
+#elif defined(CRT_BEGIN) /* ! CRT_BEGIN1 */
+
+#ifndef USE_CRT_BEGIN1
+# ifdef USE_EH_FRAME_REGISTRY
+/* Stick a label at the beginning of the frame unwind info so we can register
+ and deregister it with the exception handling library code. */
+STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
+ __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
+ = { };
+# endif /* USE_EH_FRAME_REGISTRY */
+#else /* USE_CRT_BEGIN1 */
+# ifdef USE_EH_FRAME_REGISTRY
+extern EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[];
+# endif /* USE_EH_FRAME_REGISTRY */
+#endif /* USE_CRT_BEGIN1 */
/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
@@ -246,14 +277,6 @@ STATIC func_ptr __DTOR_LIST__[1]
#endif /* __DTOR_LIST__ alternatives */
#endif /* USE_INITFINI_ARRAY */
-#ifdef USE_EH_FRAME_REGISTRY
-/* Stick a label at the beginning of the frame unwind info so we can register
- and deregister it with the exception handling library code. */
-STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
- __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
- = { };
-#endif /* USE_EH_FRAME_REGISTRY */
-
#ifdef JCR_SECTION_NAME
/* Stick a label at the beginning of the java class registration info
so we can register them properly. */
@@ -584,7 +607,7 @@ __do_global_ctors_1(void)
#error "What are you doing with crtstuff.c, then?"
#endif
-#elif defined(CRT_END) /* ! CRT_BEGIN */
+#elif defined(CRT_END) /* ! CRT_BEGIN1 && ! CRT_BEGIN */
/* No need for .ctors/.dtors section if linker can place them in
.init_array/.fini_array section. */
@@ -752,6 +775,6 @@ __do_global_ctors (void)
#error "What are you doing with crtstuff.c, then?"
#endif
-#else /* ! CRT_BEGIN && ! CRT_END */
-#error "One of CRT_BEGIN or CRT_END must be defined."
+#else /* ! CRT_BEGIN1 && ! CRT_BEGIN && ! CRT_END */
+#error "One of CRT_BEGIN1, CRT_BEGIN or CRT_END must be defined."
#endif