From: Stan Shebs Date: Wed, 14 Feb 2018 17:15:44 +0000 (-0800) Subject: Add a --with-lld option to choose LLVMs lld linker X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6302c3ccf839007f8632964e99a3e5d038a5e9e2;p=thirdparty%2Fglibc.git Add a --with-lld option to choose LLVMs lld linker --- diff --git a/Makeconfig b/Makeconfig index 695c3f81f1b..dce9b3548d5 100644 --- a/Makeconfig +++ b/Makeconfig @@ -521,8 +521,13 @@ CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build ifeq (yes,$(build-shared)) # These indicate whether to link using the built ld.so or the installed one. +ifeq ($(with-lld),no) installed-rtld-LDFLAGS = -Wl,-dynamic-linker=$(rtlddir)/$(rtld-installed-name) built-rtld-LDFLAGS = -Wl,-dynamic-linker=$(elf-objpfx)ld.so +else +installed-rtld-LDFLAGS = -Wl,-dynamic-linker,$(rtlddir)/$(rtld-installed-name) +built-rtld-LDFLAGS = -Wl,-dynamic-linker,$(elf-objpfx)ld.so +endif ifndef rtld-LDFLAGS rtld-LDFLAGS = $(installed-rtld-LDFLAGS) @@ -907,6 +912,12 @@ ifeq ($(with-clang),yes) # Non-string format arguments come from debugging prints in ld.so. +cflags += -Wno-format-security +ifeq ($(with-lld),yes) +LDFLAGS.so += -fuse-ld=lld +LDFLAGS-rtld += -fuse-ld=lld +LDFLAGS += -fuse-ld=lld +endif + endif # with-clang == yes +cflags += $(cflags-cpu) $(+gccwarn) $(+merge-constants) $(+math-flags) \ diff --git a/configure b/configure index 8bdc71adf4f..0c64f966933 100755 --- a/configure +++ b/configure @@ -762,6 +762,7 @@ with_gd_lib with_binutils with_selinux with_clang +with_lld with_headers with_default_link enable_sanity_checks @@ -1489,6 +1490,7 @@ Optional Packages: --with-binutils=PATH specify location of binutils (as and ld) --with-selinux if building with SELinux support --with-clang if building with clang (temporary) + --with-lld if building/linking with lld (temporary) --with-headers=PATH location of system headers to use (for example /usr/src/linux/include) [default=compiler default] --with-default-link do not use explicit linker scripts @@ -3339,6 +3341,16 @@ fi config_vars="$config_vars with-clang = $with_clang" +# Check whether --with-lld was given. +if test "${with_lld+set}" = set; then : + withval=$with_lld; with_lld=$withval +else + with_lld=no +fi + +config_vars="$config_vars +with-lld = $with_lld" + # Check whether --with-headers was given. if test "${with_headers+set}" = set; then : @@ -4478,6 +4490,7 @@ $as_echo "$libc_cv_prog_ld_gnu" >&6; } gnu_ld=$libc_cv_prog_ld_gnu +if test "$with_clang" = no; then # Accept binutils 2.25 or newer. for ac_prog in $AS do @@ -4542,7 +4555,9 @@ if test $ac_verc_fail = yes; then AS=: critic_missing="$critic_missing as" fi +fi +if test "$with_lld" = no; then if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then # Accept gold 1.14 or higher for ac_prog in $LD @@ -4672,6 +4687,7 @@ if test $ac_verc_fail = yes; then LD=: critic_missing="$critic_missing GNU ld" fi +fi fi # These programs are version sensitive. diff --git a/configure.ac b/configure.ac index 34b905be980..9899b3d8483 100644 --- a/configure.ac +++ b/configure.ac @@ -144,6 +144,13 @@ AC_ARG_WITH([clang], [with_clang=$withval], [with_clang=no]) LIBC_CONFIG_VAR([with-clang], [$with_clang]) +dnl This is a temporary hack, to help with BFD LD vs LLD debugging. +AC_ARG_WITH([lld], + AC_HELP_STRING([--with-lld], + [if building/linking with lld (temporary)]), + [with_lld=$withval], + [with_lld=no]) +LIBC_CONFIG_VAR([with-lld], [$with_lld]) AC_ARG_WITH([headers], AC_HELP_STRING([--with-headers=PATH], @@ -928,12 +935,15 @@ AC_PROG_LN_S LIBC_PROG_BINUTILS +if test "$with_clang" = no; then # Accept binutils 2.25 or newer. AC_CHECK_PROG_VER(AS, $AS, --version, [GNU assembler.* \([0-9]*\.[0-9.]*\)], [2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], AS=: critic_missing="$critic_missing as") +fi +if test "$with_lld" = no; then if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then # Accept gold 1.14 or higher AC_CHECK_PROG_VER(LD, $LD, --version, @@ -946,6 +956,7 @@ else [2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], LD=: critic_missing="$critic_missing GNU ld") fi +fi # These programs are version sensitive. AC_CHECK_TOOL_PREFIX diff --git a/elf/Makefile b/elf/Makefile index e4605877a38..6aefe50ca72 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -444,9 +444,10 @@ $(objpfx)librtld.map: $(objpfx)dl-allobjs.os $(common-objpfx)libc_pic.a rm -f $@.o mv -f $@T $@ +# For lld, add to regexp below for optional address and size to be at front of line. $(objpfx)librtld.mk: $(objpfx)librtld.map Makefile LC_ALL=C \ - sed -n 's@^$(common-objpfx)\([^(]*\)(\([^)]*\.os\)) *.*$$@\1 \2@p' \ + sed -n 's@^[0-9a-f ]*$(common-objpfx)\([^(]*\)(\([^)]*\.os\)) *.*$$@\1 \2@p' \ $< | \ while read lib file; do \ case $$lib in \ diff --git a/elf/rtld.c b/elf/rtld.c index aaf8c325959..5d4f0137845 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -392,7 +392,13 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) #endif _dl_setup_hash (&GL(dl_rtld_map)); GL(dl_rtld_map).l_real = &GL(dl_rtld_map); +#if defined(__clang__) + /* Work around an lld complaint that _begin cannot have a reloc and + also be absolute because of _begin=0 on linker line. */ + GL(dl_rtld_map).l_map_start = (ElfW(Addr)) 0; +#else GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin; +#endif GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext; /* Copy the TLS related data if necessary. */