You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
416 lines
16 KiB
416 lines
16 KiB
From 95f5a9a866695da4e038aa4e6ccbbfd5d9cf63b7 Mon Sep 17 00:00:00 2001 |
|
From: Joseph Myers <joseph@codesourcery.com> |
|
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/ChangeLog b/ChangeLog |
|
index 7e270e0..dc750a5 100644 |
|
--- a/ChangeLog |
|
+++ b/ChangeLog |
|
@@ -1,5 +1,52 @@ |
|
2012-07-03 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. |
|
+ |
|
[BZ #14283] |
|
* sysdeps/ieee754/flt-32/k_rem_pio2f.c (__kernel_rem_pio2f): Shift |
|
by 7 not 8 to examine high bit of fractional part. Use volatile |
|
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 |
|
+ <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 (); |
|
+} |
|
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 <joseph@codesourcery.com> |
|
+ |
|
+ * 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 <joseph@codesourcery.com> |
|
|
|
* 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 |
|
|
|
|