From 95f5a9a866695da4e038aa4e6ccbbfd5d9cf63b7 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 3 Jul 2012 19:14:59 +0000 Subject: [PATCH] Avoid use of libgcc_s and libgcc_eh when building glibc. --- ChangeLog | 47 ++++++++++++++++++++++++++++++ Makeconfig | 68 ++++++++++++++++++++++++++++++++++++++------ Rules | 45 ++++++++++++++++++++++------- elf/Makefile | 6 +++- elf/static-stubs.c | 46 +++++++++++++++++++++++++++++ ports/ChangeLog.arm | 7 ++++ ports/sysdeps/arm/Makefile | 8 +++++ 7 files changed, 206 insertions(+), 21 deletions(-) create mode 100644 elf/static-stubs.c diff --git a/Makeconfig b/Makeconfig index 417fa50..859b588 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,8 +524,43 @@ 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 +# How to link against libgcc. Some libgcc functions, such as those +# for "long long" arithmetic or software floating point, can always be +# built without use of C library headers and do not have any global +# state so can safely be linked statically into any executable or +# shared library requiring them; these functions are in libgcc.a. +# Other functions, relating to exception handling, may require C +# library headers to build and it may not be safe to have more than +# one copy of them in a process; these functions are only in +# libgcc_s.so and libgcc_eh.a. +# +# To avoid circular dependencies when bootstrapping, it is desirable +# to avoid use of libgcc_s and libgcc_eh in building glibc. Where any +# glibc functionality (in particular, thread cancellation) requires +# exception handling, this is implemented through dlopen of libgcc_s +# to avoid unnecessary dependencies on libgcc_s by programs not using +# that functionality; executables built with glibc do not use +# exception handling other than through thread cancellation. +# +# Undefined references to functions from libgcc_eh or libgcc_s may +# arise for code built with -fexceptions. In the case of statically +# linked programs installed by glibc, unwinding will never actually +# occur at runtime and the use of elf/static-stubs.c to resolve these +# references is safe. In the case of statically linked test programs +# and test programs built with -fexceptions, unwinding may occur in +# some cases and it is preferable to link with libgcc_eh or libgcc_s +# so that the testing is as similar as possible to how programs will +# be built with the installed glibc. +# +# Some architectures have architecture-specific systems for exception +# handling that may involve undefined references to +# architecture-specific functions. On those architectures, +# gnulib-arch and static-gnulib-arch may be defined in sysdeps +# makefiles to use additional libraries for linking executables and +# shared libraries built by glibc. ifndef gnulib ifneq ($(have-cc-with-libunwind),yes) libunwind = @@ -522,8 +568,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 + . */ + +/* Avoid backtrace (and so _Unwind_Backtrace) dependencies from + sysdeps/unix/sysv/linux/libc_fatal.c. */ +#include + +#include +#include + +/* 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 (); +} diff --git a/ports/ChangeLog.arm b/ports/ChangeLog.arm index c411e1c..71e8b1b 100644 --- a/ports/ChangeLog.arm +++ b/ports/ChangeLog.arm @@ -1,3 +1,10 @@ +2012-07-03 Joseph Myers + + * sysdeps/arm/Makefile (gnulib-arch): New variable. + (static-gnulib-arch): Likewise. + [subdir = elf] ($(objpfx)libgcc-stubs.a): New rule. + [subdir = elf] (lib-noranlib): Depend on $(objpfx)libgcc-stubs.a. + 2012-06-12 Joseph Myers * sysdeps/unix/sysv/linux/arm/setcontext.S (__startcontext): Use diff --git a/ports/sysdeps/arm/Makefile b/ports/sysdeps/arm/Makefile index 5fd5136..3bdb6b3 100644 --- a/ports/sysdeps/arm/Makefile +++ b/ports/sysdeps/arm/Makefile @@ -1,8 +1,16 @@ +gnulib-arch = $(elfobjdir)/libgcc-stubs.a +static-gnulib-arch = $(elfobjdir)/libgcc-stubs.a + ifeq ($(subdir),elf) sysdep-dl-routines += tlsdesc dl-tlsdesc sysdep_routines += aeabi_unwind_cpp_pr1 find_exidx tlsdesc dl-tlsdesc sysdep-rtld-routines += aeabi_unwind_cpp_pr1 tlsdesc dl-tlsdesc shared-only-routines += aeabi_unwind_cpp_pr1 + +$(objpfx)libgcc-stubs.a: $(objpfx)aeabi_unwind_cpp_pr1.os + $(build-extra-lib) + +lib-noranlib: $(objpfx)libgcc-stubs.a endif ifeq ($(subdir),csu) -- 1.7.3.4