|
From: <sv...@va...> - 2013-03-28 15:53:29
|
tom 2013-03-28 15:53:21 +0000 (Thu, 28 Mar 2013)
New Revision: 13346
Log:
Cope with old linkers which don't support -Ttext-segment but which do
generate build-id sections. #317091. (Mark Wielaard, mj...@re...)
Modified files:
trunk/Makefile.tool.am
trunk/configure.in
trunk/coregrind/link_tool_exe_linux.in
Modified: trunk/Makefile.tool.am (+11 -3)
===================================================================
--- trunk/Makefile.tool.am 2013-03-28 10:40:53 +00:00 (rev 13345)
+++ trunk/Makefile.tool.am 2013-03-28 15:53:21 +00:00 (rev 13346)
@@ -26,8 +26,14 @@
endif
+# -Wl,--build-id=none is needed when linking tools with a linker that only
+# knows -Ttext and not -Ttext-segment. Without this flag newer ld versions
+# (2.20 and later) create a .note.gnu.build-id at the default text segment
+# address, which of course means the resulting executable
+# is unusable. So we have to tell ld not to generate that, with
+# --build-id=none unless the linker supports -Ttext-segment.
TOOL_LDFLAGS_COMMON_LINUX = \
- -static -nodefaultlibs -nostartfiles -u _start
+ -static -nodefaultlibs -nostartfiles -u _start @FLAG_NO_BUILD_ID@
TOOL_LDFLAGS_COMMON_DARWIN = \
-nodefaultlibs -nostartfiles -Wl,-u,__start -Wl,-e,__start
@@ -57,10 +63,12 @@
# MIPS Linux default start symbol is __start, not _start like on x86 or amd
TOOL_LDFLAGS_MIPS32_LINUX = \
- -static -nodefaultlibs -nostartfiles -u __start @FLAG_M32@
+ -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
+ @FLAG_M32@
TOOL_LDFLAGS_MIPS64_LINUX = \
- -static -nodefaultlibs -nostartfiles -u __start @FLAG_M64@
+ -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
+ @FLAG_M64@
# On Android we must ask for non-executable stack, not sure why.
if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX
Modified: trunk/coregrind/link_tool_exe_linux.in (+12 -4)
===================================================================
--- trunk/coregrind/link_tool_exe_linux.in 2013-03-28 10:40:53 +00:00 (rev 13345)
+++ trunk/coregrind/link_tool_exe_linux.in 2013-03-28 15:53:21 +00:00 (rev 13346)
@@ -27,15 +27,23 @@
# directly. It is only run as part of the build process, with
# carefully constrained inputs.
#
-# Linux specific complication:
+# Linux specific complications:
#
# - need to support both old GNU ld and gold: use -Ttext= to
# set the text segment address if that is all we have. We really
# need -Ttext-segment. Otherwise with GNU ld sections or notes
-# (like the build-id) don't get at the desired address. Luckily
-# -Ttext does the right thing for gold. So configure checks for
-# us and sets FLAG_T_TEXT.
+# (like the build-id) don't get at the desired address. But older
+# linkers only know about -Ttext, not -Ttext-segment. So configure
+# checks for us and sets FLAG_T_TEXT.
#
+# - If all we have is -Ttext, then we need to pass --build-id=none
+# (that is, -Wl,--build-id=none to gcc) if it accepts it, to ensure
+# the linker doesn't add a notes section which ends up at the default
+# load address and so defeats our attempts to keep that address clear
+# for the client. However, older linkers don't support this flag,
+# so it is tested for by configure.in and is shipped to us as part of
+# argv[2 ..].
+#
# So: what we actually do:
#
# pass the specified command to the linker as-is, except, add
Modified: trunk/configure.in (+32 -0)
===================================================================
--- trunk/configure.in 2013-03-28 10:40:53 +00:00 (rev 13345)
+++ trunk/configure.in 2013-03-28 15:53:21 +00:00 (rev 13346)
@@ -1723,15 +1723,47 @@
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([ ], [return 0;])],
[
+ linker_using_t_text="no"
AC_SUBST([FLAG_T_TEXT], ["-Ttext-segment"])
AC_MSG_RESULT([yes])
], [
+ linker_using_t_text="yes"
AC_SUBST([FLAG_T_TEXT], ["-Ttext"])
AC_MSG_RESULT([no])
])
CFLAGS=$safe_CFLAGS
+# If the linker only supports -Ttext (not -Ttext-segment) then we will
+# have to strip any build-id ELF NOTEs from the staticly linked tools.
+# Otherwise the build-id NOTE might end up at the default load address.
+# (Pedantically if the linker is gold then -Ttext is fine, but newer
+# gold versions also support -Ttext-segment. So just assume that unless
+# we can use -Ttext-segment we need to strip the build-id NOTEs.
+if test "x${linker_using_t_text}" == "xyes"; then
+AC_MSG_NOTICE([ld -Ttext used, need to strip build-id NOTEs.])
+# does the linker support -Wl,--build-id=none ? Note, it's
+# important that we test indirectly via whichever C compiler
+# is selected, rather than testing /usr/bin/ld or whatever
+# directly.
+AC_MSG_CHECKING([if the linker accepts -Wl,--build-id=none])
+safe_CFLAGS=$CFLAGS
+CFLAGS="-Wl,--build-id=none"
+AC_LINK_IFELSE(
+[AC_LANG_PROGRAM([ ], [return 0;])],
+[
+ AC_SUBST([FLAG_NO_BUILD_ID], ["-Wl,--build-id=none"])
+ AC_MSG_RESULT([yes])
+], [
+ AC_SUBST([FLAG_NO_BUILD_ID], [""])
+ AC_MSG_RESULT([no])
+])
+else
+AC_MSG_NOTICE([ld -Ttext-segment used, no need to strip build-id NOTEs.])
+AC_SUBST([FLAG_NO_BUILD_ID], [""])
+fi
+CFLAGS=$safe_CFLAGS
+
# does the ppc assembler support "mtocrf" et al?
AC_MSG_CHECKING([if ppc32/64 as supports mtocrf/mfocrf])
|