This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Avoid use of libgcc_s and libgcc_eh when building glibc


As discussed in a thread started at
<http://sourceware.org/ml/libc-alpha/2012-03/msg00960.html> (continued
<http://sourceware.org/ml/libc-alpha/2012-05/msg00635.html>), for
smooth bootstraps of cross tools without a prebuilt libc it is
desirable that building libc, and all the miscellaneous executables
and shared libraries installed with it, should not require libgcc_eh
or libgcc_s, so it will work with a minimal libgcc such as GCC can
build with -Dinhibit_libc without needing any libc headers or prebuilt
libc.  It is also desirable that the resulting libc be the same as you
get if you build libc when you do have a prebuilt libc the compiler
can find, and that the build tree is just as capable of running tests
in either case.

I sent a prototype patch in
<http://sourceware.org/ml/libc-alpha/2012-05/msg00705.html> to avoid
libgcc_eh and libgcc_s for building glibc, while still using them to
build tests.  Here is a cleaned up version of this patch that I now
propose for inclusion.  Various variables are refactored to reduce
duplication arising from the separate variants for building test and
non-test programs.

For the issue of architecture-specific stubs being needed for unwind
functions, I added new variables gnulib-arch and static-gnulib-arch
that sysdeps makefiles can define.  This makes the ARM changes
(attached) cleaner than before - though I'd welcome advice on any
better way there may be for an architecture to cause a non-installed
.a library to be built (a library is needed rather than just an object
file because the $(gnulib*) variables can get listed more than once on
the command link when linking).  It also means that if any
architecture has more fundamental difficulties building glibc without
needing libgcc_eh or libgcc_s already built, it can just define those
variables to, respectively, $(libgcc_eh) and -lgcc_eh $(libunwind),
and binaries should continue to be linked as they are at present.

I've tested this patch for x86_64 and also done a test build for ARM.
To go in it will certainly need more architecture testing (libc
architectures and IA64) - but since it seems likely that review will
point out changes that should be made, perhaps we could sort out any
such changes first so the architecture maintainers are testing a patch
that could, subject to such testing, go in?

2012-05-28  Joseph Myers  <joseph@codesourcery.com>

	* Makeconfig [!+link] (+link-before-libc): New variable.
	[!+link] (+link-after-libc): Likewise.
	[!+link] (+link-tests): Likewise.
	[!+link] (+link): Define in terms of $(+link-before-libc) and
	$(+link-after-libc).
	[!+link-static] (+link-static-before-libc): New variable.
	[!+link-static] (+link-static-after-libc): Likewise.
	[!+link-static] (+link-static-tests): Likewise.
	[!+link-static] (+link-static): Define in terms of
	$(+link-static-before-libc) and $(+link-static-after-libc).
	[build-shared] (link-libc-before-gnulib): New variable.
	[build-shared] (link-libc-tests): Likewise.
	[build-shared] (link-libc): Define in terms of
	$(link-libc-before-gnulib).
	[!build-shared] (link-libc-tests): New variable.
	(link-libc-static-tests): New variable.
	[!gnulib] (gnulib-arch): New variable.
	[!gnulib] (gnulib-tests): Likewise.
	[!gnulib] (static-gnulib-arch): Likewise.
	[!gnulib] (static-gnulib-tests): Likewise.
	[!gnulib] (gnulib): Use $(gnulib-arch).  Do not use $(libgcc_eh).
	Define with "=" instead of ":=".
	[!gnulib] (static-gnulib): Use $(static-gnulib-arch).  Do not use
	-lgcc_eh $(libunwind).  Define with "=" instead of ":=".
	* Rules (binaries-all-notests): New variable.
	(binaries-all-tests): Likewise.
	(binaries-static-notests): Likewise.
	(binaries-static-tests): Likewise.
	(binaries-all): Define using $(binaries-all-notests) and
	$(binaries-all-tests).
	(binaries-static): Define using $(binaries-static-notests) and
	$(binaries-static-tests).
	(binaries-shared-tests): New variable.
	(binaries-shared-notests): Likewise.
	(binaries-shared): Remove variable.
	($(addprefix $(objpfx),$(binaries-shared-notests))): New rule.
	($(addprefix $(objpfx),$(binaries-shared-tests))): Likewise.
	($(addprefix $(objpfx),$(binaries-shared))): Remove rule.
	($(addprefix $(objpfx),$(binaries-static-notests))): New rule.
	($(addprefix $(objpfx),$(binaries-static-tests))): Likewise.
	($(addprefix $(objpfx),$(binaries-static))): Remove rule.
	* elf/Makefile (sln-modules): New variable.
	(extra-objs): Add $(sln-modules:=.o).
	(ldconfig-modules): Add static-stubs.
	($(objpfx)sln): Depend on $(sln-modules:%=$(objpfx)%.o).
	* elf/static-stubs.c: New file.

diff --git a/Makeconfig b/Makeconfig
index b4b2963..f2d68c4 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -415,9 +415,9 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
 LDFLAGS-rtld += $(hashstyle-LDFLAGS)
 endif
 
-# Command for linking programs with the C library.
+# Commands for linking programs with the C library.
 ifndef +link
-+link = $(CC) -nostdlib -nostartfiles -o $@ \
++link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \
 	      $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
 	      $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
 	      $(addprefix $(csu-objpfx),$(start-installed-name)) \
@@ -426,7 +426,10 @@ ifndef +link
 						     $(start-installed-name))\
 			   $(+preinit) $(link-extra-libs) \
 			   $(common-objpfx)libc% $(+postinit),$^) \
-	      $(link-extra-libs) $(link-libc) $(+postctor) $(+postinit)
+	      $(link-extra-libs)
++link-after-libc = $(+postctor) $(+postinit)
++link = $(+link-before-libc) $(link-libc) $(+link-after-libc)
++link-tests = $(+link-before-libc) $(link-libc-tests) $(+link-after-libc)
 endif
 # Command for linking PIE programs with the C library.
 ifndef +link-pie
@@ -443,7 +446,7 @@ ifndef +link-pie
 endif
 # Command for statically linking programs with the C library.
 ifndef +link-static
-+link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \
++link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
 	      $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
 	      $(+preinit) $(+prector) \
@@ -451,7 +454,12 @@ ifndef +link-static
 						     $(start-installed-name))\
 			   $(+preinit) $(link-extra-libs-static) \
 			   $(common-objpfx)libc% $(+postinit),$^) \
-	      $(link-extra-libs-static) $(link-libc-static) $(+postctor) $(+postinit)
+	      $(link-extra-libs-static) $(link-libc-static)
++link-static-after-libc = $(+postctor) $(+postinit)
++link-static = $(+link-static-before-libc) $(link-libc-static) \
+	       $(+link-static-after-libc)
++link-static-tests = $(+link-static-before-libc) $(link-libc-static-tests) \
+		     $(+link-static-after-libc)
 endif
 # Command for statically linking bounded-pointer programs with the C library.
 ifndef +link-bounded
@@ -475,10 +483,12 @@ ifeq (yes,$(build-shared))
 # We need the versioned name of libc.so in the deps of $(others) et al
 # so that the symlink to libc.so is created before anything tries to
 # run the linked programs.
-link-libc = -Wl,-rpath-link=$(rpath-link) \
+link-libc-before-gnulib = -Wl,-rpath-link=$(rpath-link) \
 	    $(common-objpfx)libc.so$(libc.so-version) \
 	    $(common-objpfx)$(patsubst %,$(libtype.oS),c) \
-	    $(as-needed) $(common-objpfx)elf/ld.so $(no-as-needed) $(gnulib)
+	    $(as-needed) $(common-objpfx)elf/ld.so $(no-as-needed)
+link-libc = $(link-libc-before-gnulib) $(gnulib)
+link-libc-tests = $(link-libc-before-gnulib) $(gnulib-tests)
 # This is how to find at build-time things that will be installed there.
 rpath-dirs = math elf dlfcn nss nis rt resolv crypt
 rpath-link = \
@@ -488,6 +498,7 @@ else
 nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss)
 resolvobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)resolv)
 link-libc = $(common-objpfx)libc.a $(otherlibs) $(gnulib) $(common-objpfx)libc.a $(gnulib)
+link-libc-tests = $(common-objpfx)libc.a $(otherlibs) $(gnulib-tests) $(common-objpfx)libc.a $(gnulib-tests)
 endif
 endif
 
@@ -513,6 +524,7 @@ endif
 
 # The static libraries.
 link-libc-static = -Wl,--start-group $(common-objpfx)libc.a $(static-gnulib) -Wl,--end-group
+link-libc-static-tests = -Wl,--start-group $(common-objpfx)libc.a $(static-gnulib-tests) -Wl,--end-group
 link-libc-bounded = $(common-objpfx)libc_b.a $(gnulib) $(common-objpfx)libc_b.a
 
 ifndef gnulib
@@ -522,8 +534,12 @@ else
   libunwind = -lunwind
 endif
 libgcc_eh := -Wl,--as-needed -lgcc_s $(libunwind) -Wl,--no-as-needed
-gnulib := -lgcc $(libgcc_eh)
-static-gnulib := -lgcc -lgcc_eh $(libunwind)
+gnulib-arch =
+gnulib = -lgcc $(gnulib-arch)
+gnulib-tests := -lgcc $(libgcc_eh)
+static-gnulib-arch =
+static-gnulib = -lgcc $(static-gnulib-arch)
+static-gnulib-tests := -lgcc -lgcc_eh $(libunwind)
 libc.so-gnulib := -lgcc
 endif
 +preinit = $(addprefix $(csu-objpfx),crti.o)
diff --git a/Rules b/Rules
index 3c61a29..17d938e 100644
--- a/Rules
+++ b/Rules
@@ -1,5 +1,4 @@
-# Copyright (C) 1991-2000,2002,2003,2004,2005,2006,2011
-#	Free Software Foundation, Inc.
+# Copyright (C) 1991-2012 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
@@ -103,29 +102,46 @@ xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-bp.out)
 endif
 
 ifeq ($(build-programs),yes)
-binaries-all = $(others) $(sysdep-others) $(tests) $(xtests) $(test-srcs)
-binaries-static = $(others-static) $(tests-static) $(xtests-static)
+binaries-all-notests = $(others) $(sysdep-others)
+binaries-all-tests = $(tests) $(xtests) $(test-srcs)
+binaries-all = $(binaries-all-notests) $(binaries-all-tests)
+binaries-static-notests = $(others-static)
+binaries-static-tests = $(tests-static) $(xtests-static)
+binaries-static = $(binaries-static-notests) $(binaries-static-tests)
 ifeq (yesyes,$(have-fpie)$(build-shared))
 binaries-pie = $(others-pie) $(tests-pie) $(xtests-pie)
 else
 binaries-pie =
 endif
 else
-binaries-all = $(tests) $(xtests) $(test-srcs)
+binaries-all-notests =
+binaries-all-tests = $(tests) $(xtests) $(test-srcs)
+binaries-all = $(binaries-all-tests)
+binaries-static-notests =
+binaries-static-tests =
 binaries-static =
 binaries-pie =
 endif
 
-binaries-shared = $(filter-out $(binaries-pie) $(binaries-static), \
-			       $(binaries-all))
+binaries-shared-tests = $(filter-out $(binaries-pie) $(binaries-static), \
+				     $(binaries-all-tests))
+binaries-shared-notests = $(filter-out $(binaries-pie) $(binaries-static), \
+				       $(binaries-all-notests))
 
-ifneq "$(strip $(binaries-shared))" ""
-$(addprefix $(objpfx),$(binaries-shared)): %: %.o \
+ifneq "$(strip $(binaries-shared-notests))" ""
+$(addprefix $(objpfx),$(binaries-shared-notests)): %: %.o \
   $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
   $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
 	$(+link)
 endif
 
+ifneq "$(strip $(binaries-shared-tests))" ""
+$(addprefix $(objpfx),$(binaries-shared-tests)): %: %.o \
+  $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
+  $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
+	$(+link-tests)
+endif
+
 ifneq "$(strip $(binaries-pie))" ""
 $(addprefix $(objpfx),$(binaries-pie)): %: %.o \
   $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
@@ -133,13 +149,20 @@ $(addprefix $(objpfx),$(binaries-pie)): %: %.o \
 	$(+link-pie)
 endif
 
-ifneq "$(strip $(binaries-static))" ""
-$(addprefix $(objpfx),$(binaries-static)): %: %.o \
+ifneq "$(strip $(binaries-static-notests))" ""
+$(addprefix $(objpfx),$(binaries-static-notests)): %: %.o \
   $(sort $(filter $(common-objpfx)lib%,$(link-libc-static))) \
   $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
 	$(+link-static)
 endif
 
+ifneq "$(strip $(binaries-static-tests))" ""
+$(addprefix $(objpfx),$(binaries-static-tests)): %: %.o \
+  $(sort $(filter $(common-objpfx)lib%,$(link-libc-static-tests))) \
+  $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
+	$(+link-static-tests)
+endif
+
 ifeq ($(build-bounded),yes)
 binaries-bounded = $(addsuffix -bp,$(tests) $(xtests) $(test-srcs))
 $(addprefix $(objpfx),$(binaries-bounded)): %-bp: %.ob \
diff --git a/elf/Makefile b/elf/Makefile
index 0c26ce5..9054199 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -71,6 +71,8 @@ others		= sprof sln pldd
 install-bin	= sprof pldd
 others-static   = sln
 install-rootsbin = sln
+sln-modules	:= static-stubs
+extra-objs	+= $(sln-modules:=.o)
 
 ifeq (yes,$(use-ldconfig))
 ifeq (yes,$(build-shared))
@@ -78,7 +80,7 @@ others-static	+= ldconfig
 others		+= ldconfig
 install-rootsbin += ldconfig
 
-ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon
+ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon static-stubs
 extra-objs	+= $(ldconfig-modules:=.o)
 endif
 endif
@@ -411,6 +413,8 @@ $(objpfx)ldd: ldd.bash.in $(common-objpfx)soversions.mk \
 
 $(objpfx)sprof: $(libdl)
 
+$(objpfx)sln: $(sln-modules:%=$(objpfx)%.o)
+
 $(objpfx)ldconfig: $(ldconfig-modules:%=$(objpfx)%.o)
 
 $(objpfx)pldd: $(pldd-modules:%=$(objpfx)%.o)
diff --git a/elf/static-stubs.c b/elf/static-stubs.c
new file mode 100644
index 0000000..6c5eebc
--- /dev/null
+++ b/elf/static-stubs.c
@@ -0,0 +1,46 @@
+/* Stub implementations of functions to link into statically linked
+   programs without needing libgcc_eh.
+   Copyright (C) 2012 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Avoid backtrace (and so _Unwind_Backtrace) dependencies from
+   sysdeps/unix/sysv/linux/libc_fatal.c.  */
+#include <sysdeps/posix/libc_fatal.c>
+
+#include <stdlib.h>
+#include <unwind.h>
+
+/* These programs do not use thread cancellation, so _Unwind_Resume
+   and the personality routine are never actually called.  */
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc __attribute__ ((unused)))
+{
+  abort ();
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version __attribute__ ((unused)),
+		      _Unwind_Action actions __attribute__ ((unused)),
+		      _Unwind_Exception_Class exception_class
+		      __attribute__ ((unused)),
+		      struct _Unwind_Exception *ue_header
+		      __attribute__ ((unused)),
+		      struct _Unwind_Context *context __attribute__ ((unused)))
+{
+  abort ();
+}

-- 
Joseph S. Myers
joseph@codesourcery.com

Attachment: glibc-gcc_s-arm-v2
Description: Text document


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