This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] [BZ #14995] glibc fails to build if gold is the default linker, even if ld.bfd is available
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Tue, 10 Mar 2015 05:57:33 -0700
- Subject: [PATCH] [BZ #14995] glibc fails to build if gold is the default linker, even if ld.bfd is available
- Authentication-results: sourceware.org; auth=none
Use gold to build glibc exposed some serious gold bugs. I opened:
https://sourceware.org/bugzilla/show_bug.cgi?id=18102
https://sourceware.org/bugzilla/show_bug.cgi?id=18103
and noted:
https://sourceware.org/bugzilla/show_bug.cgi?id=14995#c10
This patch adds --enable-gold to use gold to build glibc. It can be
used to work on gold issues. If --enable-gold isn't used, it will check
if gold is the default linker and -fuse-ld=bfd is available. If gold
is the default linker, uses -fuse-ld=bfd to create shared libraries if
it is available. Tested on x32, x86-64 and x86-32. OK for master?
H.J.
----
The gold linker has no builtin default linker script and it can't be
to create shared libraries. Unless --enable-gold is used, it should
only be used to create executables. Use -fuse-ld=bfd to create shared
libraries.
[BZ #14995]
* Makerules (shlib-LDFLAGS): New.
($(common-objpfx)shlib.lds): Use it.
(build-shlib): Likewise.
(build-module-helper): Likewise.
($(common-objpfx)libc_pic.os): Likewise.
* config.make.in (use-bfd): New.
* configure: Regenerated.
* configure.ac: Add --enable-gold.
Accept gold 1.11 or higher.
(libc_cv_cc_use_bfd): Set to yes if -fuse-ld=bfd works. AC_SUBST.
(LDBFDFLAGS): New.
Use $LDBFDFLAGS to check if default -shared layout is sufficient.
---
Makerules | 13 ++++--
config.make.in | 1 +
configure | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
configure.ac | 65 ++++++++++++++++++++++++---
4 files changed, 205 insertions(+), 13 deletions(-)
diff --git a/Makerules b/Makerules
index c79915f..1b0ded0 100644
--- a/Makerules
+++ b/Makerules
@@ -517,6 +517,11 @@ $(LINK.o) -shared $(static-libgcc) -Wl,-O1 $(sysdep-LDFLAGS) \
-L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
endef
+ifeq (yes,$(use-bfd))
+# Use BFD linker to create shared libraries.
+shlib-LDFLAGS = -fuse-ld=bfd
+endif
+
ifeq (yes,$(use-default-link))
# If the linker is good enough, we can let it use its default linker script.
shlib-lds =
@@ -528,7 +533,7 @@ $(common-objpfx)shlib.lds: $(common-objpfx)config.make $(..)Makerules
$(LINK.o) -shared -Wl,-O1 \
-nostdlib -nostartfiles \
$(sysdep-LDFLAGS) $(rtld-LDFLAGS) $(LDFLAGS.so) \
- -Wl,--verbose 2>&1 | \
+ $(shlib-LDFLAGS) -Wl,--verbose 2>&1 | \
sed > $@T \
-e '/^=========/,/^=========/!d;/^=========/d' \
$(if $(filter yes,$(have-hash-style)), \
@@ -562,7 +567,7 @@ shlib-lds-flags = -T $(shlib-lds)
endif
define build-shlib
-$(build-shlib-helper) -o $@ $(shlib-lds-flags) \
+$(build-shlib-helper) -o $@ $(shlib-lds-flags) $(shlib-LDFLAGS) \
$(csu-objpfx)abi-note.o $(build-shlib-objlist)
endef
@@ -570,7 +575,7 @@ define build-module-helper
$(LINK.o) -shared $(static-libgcc) $(sysdep-LDFLAGS) $(rtld-LDFLAGS) \
$(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) \
-B$(csu-objpfx) $(load-map-file) \
- $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \
+ $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) $(shlib-LDFLAGS) \
-L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
endef
@@ -618,7 +623,7 @@ endif
# from being allocated in libc.so, which introduces evil dependencies
# between libc.so and ld.so, which can make it impossible to upgrade.
$(common-objpfx)libc_pic.os: $(common-objpfx)libc_pic.a
- $(LINK.o) -nostdlib -nostartfiles -r -o $@ \
+ $(LINK.o) -nostdlib -nostartfiles -r -o $@ $(shlib-LDFLAGS) \
$(LDFLAGS-c_pic.os) -Wl,-d $(whole-archive) $^ -o $@
ifeq (,$(strip $(shlib-lds-flags)))
diff --git a/config.make.in b/config.make.in
index ad4dd30..c2c05e3 100644
--- a/config.make.in
+++ b/config.make.in
@@ -94,6 +94,7 @@ use-nscd = @use_nscd@
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
build-pt-chown = @build_pt_chown@
enable-lock-elision = @enable_lock_elision@
+use-bfd = @libc_cv_cc_use_bfd@
# Build tools.
CC = @CC@
diff --git a/configure b/configure
index 71cc6bb..671d9e4 100755
--- a/configure
+++ b/configure
@@ -648,6 +648,8 @@ SED
MAKEINFO
MSGFMT
MAKE
+libc_cv_cc_use_bfd
+LD_BFD
LD
AS
OBJCOPY
@@ -773,6 +775,7 @@ enable_multi_arch
enable_nss_crypt
enable_obsolete_rpc
enable_systemtap
+enable_gold
enable_build_nscd
enable_nscd
enable_pt_chown
@@ -1437,6 +1440,7 @@ Optional Features:
--enable-obsolete-rpc build and install the obsolete RPC code for
link-time usage
--enable-systemtap enable systemtap static probe points [default=no]
+ --enable-gold use gold to build glibc [default=no]
--disable-build-nscd disable building and installing the nscd daemon
--disable-nscd library functions will not contact the nscd daemon
--enable-pt_chown Enable building and installing pt_chown
@@ -3801,6 +3805,14 @@ See \`config.log' for more details" "$LINENO" 5; }
fi
fi
+# Check whether --enable-gold was given.
+if test "${enable_gold+set}" = set; then :
+ enableval=$enable_gold; enable_gold=$enableval
+else
+ enable_gold=no
+fi
+
+
# Check whether --enable-build-nscd was given.
if test "${enable_build_nscd+set}" = set; then :
enableval=$enable_build_nscd; build_nscd=$enableval
@@ -4647,7 +4659,11 @@ if test $ac_verc_fail = yes; then
AS=: critic_missing="$critic_missing as"
fi
-for ac_prog in $LD
+
+# Accept gold 1.11 or higher
+if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then
+ ld_is_gold=yes
+ for ac_prog in $LD
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@@ -4695,7 +4711,115 @@ else
# Found it, now check the version.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5
$as_echo_n "checking version of $LD... " >&6; }
- ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
+ ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU gold.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
+ case $ac_prog_version in
+ '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+ 1.1[1-9]*|1.[2-9][0-9]*|1.1[0-9][0-9]*|[2-9].*|[1-9][0-9]*)
+ ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
+ *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
+
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5
+$as_echo "$ac_prog_version" >&6; }
+fi
+if test $ac_verc_fail = yes; then
+ LD=:
+fi
+
+ case $LD in
+ *ld.gold) LD_BFD="`echo $LD | sed -e 's/.gold$/.bfd/'`";;
+ *) LD_BFD=$LD;;
+ esac
+else
+ ld_is_gold=no
+ LD_BFD=$LD
+fi
+LDBFDFLAGS=
+# The gold linker has no builtin default linker script and it can't be
+# to create shared libraries. Unless --enable-gold is used, it should
+# only be used to create executables. Use -fuse-ld=bfd to create shared
+# libraries if it works.
+if test $ld_is_gold = no || test $enable_gold = no; then
+ if test $ld_is_gold = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fuse-ld=bfd" >&5
+$as_echo_n "checking if $CC accepts -fuse-ld=bfd... " >&6; }
+if ${libc_cv_cc_use_bfd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+int main (void) { return 0; }
+EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fuse-ld=bfd -nostdlib -nostartfiles -o conftest conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ libc_cv_cc_use_bfd=yes
+ LDBFDFLAGS="-fuse-ld=bfd"
+ else
+ libc_cv_cc_use_bfd=no
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_use_bfd" >&5
+$as_echo "$libc_cv_cc_use_bfd" >&6; }
+ if test "x$libc_cv_cc_use_bfd" != xyes; then
+ as_fn_error $? "${CC-cc} does not support -fuse-ld=bfd" "$LINENO" 5
+ fi
+ else
+ libc_cv_cc_use_bfd=no
+ fi
+ for ac_prog in $LD_BFD
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LD_BFD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LD_BFD"; then
+ ac_cv_prog_LD_BFD="$LD_BFD" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LD_BFD="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LD_BFD=$ac_cv_prog_LD_BFD
+if test -n "$LD_BFD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD_BFD" >&5
+$as_echo "$LD_BFD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$LD_BFD" && break
+done
+
+if test -z "$LD_BFD"; then
+ ac_verc_fail=yes
+else
+ # Found it, now check the version.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD_BFD" >&5
+$as_echo_n "checking version of $LD_BFD... " >&6; }
+ ac_prog_version=`$LD_BFD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
case $ac_prog_version in
'') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*)
@@ -4707,7 +4831,14 @@ $as_echo_n "checking version of $LD... " >&6; }
$as_echo "$ac_prog_version" >&6; }
fi
if test $ac_verc_fail = yes; then
- LD=: critic_missing="$critic_missing ld"
+ LD=:
+fi
+
+else
+ libc_cv_cc_use_bfd=no
+fi
+if test "$LD" = ":"; then
+ critic_missing="$critic_missing ld"
fi
@@ -6241,7 +6372,7 @@ else
.string "GNU"
.string "bar"
EOF
- if { ac_try=' ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&5'
+ if { ac_try=' ${CC-cc} $ASFLAGS $LDBFDFLAGS -shared -o conftest.so conftest.s 1>&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
diff --git a/configure.ac b/configure.ac
index 678c739..cb341d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -345,6 +345,12 @@ void foo (int i, void *p)
fi
fi
+AC_ARG_ENABLE(gold,
+ [AS_HELP_STRING([--enable-gold],
+ [use gold to build glibc @<:@default=no@:>@])],
+ [enable_gold=$enableval],
+ [enable_gold=no])
+
AC_ARG_ENABLE([build-nscd],
[AS_HELP_STRING([--disable-build-nscd],
[disable building and installing the nscd daemon])],
@@ -933,10 +939,59 @@ AC_CHECK_PROG_VER(AS, $AS, --version,
[GNU assembler.* \([0-9]*\.[0-9.]*\)],
[2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
AS=: critic_missing="$critic_missing as")
-AC_CHECK_PROG_VER(LD, $LD, --version,
- [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)],
- [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
- LD=: critic_missing="$critic_missing ld")
+
+# Accept gold 1.11 or higher
+if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then
+ ld_is_gold=yes
+ AC_CHECK_PROG_VER(LD, $LD, --version,
+ [GNU gold.* \([0-9][0-9]*\.[0-9.]*\)],
+ [1.1[1-9]*|1.[2-9][0-9]*|1.1[0-9][0-9]*|[2-9].*|[1-9][0-9]*],
+ LD=:)
+ case $LD in
+ *ld.gold) LD_BFD="`echo $LD | sed -e 's/.gold$/.bfd/'`";;
+ *) LD_BFD=$LD;;
+ esac
+else
+ ld_is_gold=no
+ LD_BFD=$LD
+fi
+LDBFDFLAGS=
+# The gold linker has no builtin default linker script and it can't be
+# to create shared libraries. Unless --enable-gold is used, it should
+# only be used to create executables. Use -fuse-ld=bfd to create shared
+# libraries if it works.
+if test $ld_is_gold = no || test $enable_gold = no; then
+ if test $ld_is_gold = yes; then
+ AC_CACHE_CHECK(if $CC accepts -fuse-ld=bfd,
+ libc_cv_cc_use_bfd, [dnl
+ cat > conftest.c <<EOF
+int main (void) { return 0; }
+EOF
+ if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -fuse-ld=bfd -nostdlib -nostartfiles -o conftest conftest.c])
+ then
+ libc_cv_cc_use_bfd=yes
+ LDBFDFLAGS="-fuse-ld=bfd"
+ else
+ libc_cv_cc_use_bfd=no
+ fi
+ rm -f conftest*])
+ if test "x$libc_cv_cc_use_bfd" != xyes; then
+ AC_MSG_ERROR([${CC-cc} does not support -fuse-ld=bfd])
+ fi
+ else
+ libc_cv_cc_use_bfd=no
+ fi
+ AC_CHECK_PROG_VER(LD_BFD, $LD_BFD, --version,
+ [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)],
+ [2.1[0-9][0-9]*|2.2[2-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
+ LD=:)
+else
+ libc_cv_cc_use_bfd=no
+fi
+if test "$LD" = ":"; then
+ critic_missing="$critic_missing ld"
+fi
+AC_SUBST(libc_cv_cc_use_bfd)
# These programs are version sensitive.
AC_CHECK_TOOL_PREFIX
@@ -1472,7 +1527,7 @@ if test "$use_default_link" = default; then
.string "bar"
EOF
if AC_TRY_COMMAND([dnl
- ${CC-cc} $ASFLAGS -shared -o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD]) &&
+ ${CC-cc} $ASFLAGS $LDBFDFLAGS -shared -o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD]) &&
ac_try=`$READELF -S conftest.so | sed -n \
['${x;p;}
s/^ *\[ *[1-9][0-9]*\] *\([^ ][^ ]*\) *\([^ ][^ ]*\) .*$/\2 \1/
--
2.1.0