diff options
author | Jing Yu <jingyu@google.com> | 2010-06-08 14:41:10 -0700 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2010-06-08 14:41:10 -0700 |
commit | 289c95d00ec591cffa5b705641ffcbdacb7c0d5c (patch) | |
tree | 683802b0de387c442324d78d4e1b27ef08a8d593 | |
parent | 53b6ed3bceea971857c996b6dcb96de96b99335f (diff) | |
download | toolchain_binutils-289c95d00ec591cffa5b705641ffcbdacb7c0d5c.zip toolchain_binutils-289c95d00ec591cffa5b705641ffcbdacb7c0d5c.tar.gz toolchain_binutils-289c95d00ec591cffa5b705641ffcbdacb7c0d5c.tar.bz2 |
Binutils sources for toolchain checked in on 06/03/2010.
Contains packages that fix assembler bugs, and kernel build problem with gold.
See binutils-2.19/README.android for details.
Change-Id: I69c754211f5d508266ba24cf144f54f6aed58f31
-rw-r--r-- | binutils-2.19/Makefile.def | 1 | ||||
-rw-r--r-- | binutils-2.19/Makefile.in | 1 | ||||
-rw-r--r-- | binutils-2.19/README.android | 51 | ||||
-rwxr-xr-x | binutils-2.19/configure | 76 | ||||
-rw-r--r-- | binutils-2.19/configure.ac | 78 | ||||
-rw-r--r-- | binutils-2.19/gold/Makefile.am | 17 | ||||
-rw-r--r-- | binutils-2.19/gold/Makefile.in | 19 | ||||
-rw-r--r-- | binutils-2.19/gold/arm.cc | 491 | ||||
-rw-r--r-- | binutils-2.19/gold/configure | 31 | ||||
-rw-r--r-- | binutils-2.19/gold/configure.ac | 27 | ||||
-rw-r--r-- | binutils-2.19/gold/gold.cc | 10 | ||||
-rw-r--r-- | binutils-2.19/gold/merge.cc | 28 | ||||
-rw-r--r-- | binutils-2.19/gold/merge.h | 84 | ||||
-rw-r--r-- | binutils-2.19/gold/object.cc | 16 | ||||
-rw-r--r-- | binutils-2.19/gold/output.cc | 251 | ||||
-rw-r--r-- | binutils-2.19/gold/output.h | 789 | ||||
-rw-r--r-- | binutils-2.19/gold/script-sections.cc | 55 | ||||
-rw-r--r-- | binutils-2.19/gold/target-reloc.h | 15 | ||||
-rw-r--r-- | binutils-2.19/gold/target.h | 30 | ||||
-rw-r--r-- | binutils-2.19/ld/Makefile.am | 37 | ||||
-rw-r--r-- | binutils-2.19/ld/Makefile.in | 112 | ||||
-rwxr-xr-x | binutils-2.19/ld/configure | 58 | ||||
-rw-r--r-- | binutils-2.19/ld/configure.in | 23 |
23 files changed, 1635 insertions, 665 deletions
diff --git a/binutils-2.19/Makefile.def b/binutils-2.19/Makefile.def index 832fc42..382ce09 100644 --- a/binutils-2.19/Makefile.def +++ b/binutils-2.19/Makefile.def @@ -378,6 +378,7 @@ dependencies = { module=all-ld; on=all-build-bison; }; dependencies = { module=all-ld; on=all-build-byacc; }; dependencies = { module=all-ld; on=all-build-flex; }; dependencies = { module=all-ld; on=all-intl; }; +dependencies = { module=install-ld; on=install-gold; }; dependencies = { module=configure-gold; on=configure-intl; }; dependencies = { module=all-gold; on=all-libiberty; }; dependencies = { module=all-gold; on=all-intl; }; diff --git a/binutils-2.19/Makefile.in b/binutils-2.19/Makefile.in index 0305d28..013809d 100644 --- a/binutils-2.19/Makefile.in +++ b/binutils-2.19/Makefile.in @@ -53314,6 +53314,7 @@ all-stageb3g2-ld: maybe-all-stageb3g2-intl all-stage4-ld: maybe-all-stage4-intl all-stageprofile-ld: maybe-all-stageprofile-intl all-stagefeedback-ld: maybe-all-stagefeedback-intl +install-ld: maybe-install-gold configure-gold: maybe-configure-intl configure-stage1-gold: maybe-configure-stage1-intl diff --git a/binutils-2.19/README.android b/binutils-2.19/README.android index 6447357..1231282 100644 --- a/binutils-2.19/README.android +++ b/binutils-2.19/README.android @@ -1,3 +1,54 @@ +2010-06-02 Doug Kwan <dougkwan@google.com> + + Backport upstream patches to support dual-linker configuration. + + gcc change for rev 158786. + http://sourceware.org/ml/binutils-cvs/2010-04/msg00138.html + http://sourceware.org/ml/binutils-cvs/2010-04/msg00142.html + +2010-05-27 Doug Kwan <dougkwan@google.com> + + Backport upstream patches to make gold build ARM Linux kernel + correctly. + + http://sourceware.org/ml/binutils-cvs/2010-05/msg00068.html + http://sourceware.org/ml/binutils-cvs/2010-05/msg00082.html + http://sourceware.org/ml/binutils-cvs/2010-05/msg00104.html + http://sourceware.org/ml/binutils-cvs/2010-05/msg00113.html + + Changed files: + + arm.cc + merge.cc + merge.h + object.cc + output.cc + output.h + script-sections.cc + target-reloc.h + target.h + +2010-04-15 Doug Kwan <dougkwan@google.com> + + Backport upstream patch to fix linker crash. + + http://sourceware.org/ml/binutils-cvs/2010-04/msg00078.html + + Changed files: + + gold/arm.cc + gold/gold.cc + +2010-04-13 Doug Kwan <dougkwan@google.com> + + Backport upstream patch to fix crash during ARM kernel build. + + http://sourceware.org/ml/binutils-cvs/2010-04/msg00067.html + + Changed files: + + gold/arm.cc + 2010-04-09 Doug Kwan <dougkwan@google.com> Backport upstream patch to add support for NOLOAD section type in diff --git a/binutils-2.19/configure b/binutils-2.19/configure index 2c7815f..49e7694 100755 --- a/binutils-2.19/configure +++ b/binutils-2.19/configure @@ -932,7 +932,7 @@ if test -n "$ac_init_help"; then Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-gold use gold instead of ld + --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]] --enable-libada build libada directory --enable-libssp build libssp directory --enable-stage1-languages[=all] choose additional languages to build during @@ -1880,8 +1880,8 @@ host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib l # know that we are building the simulator. # binutils, gas and ld appear in that order because it makes sense to run # "make check" in that particular order. -# If --enable-gold is used, "gold" will replace "ld". -host_tools="texinfo byacc flex bison binutils gas ld fixincludes gcc sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" +# If --enable-gold is used, "gold" may replace "ld". +host_tools="byacc flex bison binutils gas ld fixincludes gcc sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" # libgcj represents the runtime libraries only used by gcj. libgcj="target-libffi \ @@ -2036,39 +2036,61 @@ case ${with_newlib} in esac # Handle --enable-gold. +# --enable-gold Build only gold +# --disable-gold [default] Build only ld +# --enable-gold=both Build both gold and ld, ld is default +# --enable-gold=both/ld Same +# --enable-gold=both/gold Build both gold and ld, gold is default, ld is renamed ld.bfd -# Check whether --enable-gold or --disable-gold was given. + # Check whether --enable-gold or --disable-gold was given. if test "${enable_gold+set}" = set; then enableval="$enable_gold" ENABLE_GOLD=$enableval else ENABLE_GOLD=no fi; -if test "${ENABLE_GOLD}" = "yes"; then - # Check for ELF target. - is_elf=no - case "${target}" in - *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ - | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ - | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2*) - case "${target}" in - *-*-linux*aout* | *-*-linux*oldld*) - ;; - *) - is_elf=yes - ;; - esac - esac - - if test "$is_elf" = "yes"; then - # Check for target supported by gold. + case "${ENABLE_GOLD}" in + yes|both|both/gold|both/ld) + # Check for ELF target. + is_elf=no case "${target}" in - i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) - configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" - ;; + *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ + | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ + | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*) + case "${target}" in + *-*-linux*aout* | *-*-linux*oldld*) + ;; + *) + is_elf=yes + ;; + esac + esac + + if test "$is_elf" = "yes"; then + # Check for target supported by gold. + case "${target}" in + i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) + case "${ENABLE_GOLD}" in + both*) + configdirs="$configdirs gold" + ;; + *) + configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" + ;; + esac + ENABLE_GOLD=yes + ;; + esac + fi + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: invalid --enable-gold argument" >&5 +echo "$as_me: error: invalid --enable-gold argument" >&2;} + { (exit 1); exit 1; }; } + ;; esac - fi -fi # Configure extra directories which are host specific diff --git a/binutils-2.19/configure.ac b/binutils-2.19/configure.ac index c31e255..a5b844a 100644 --- a/binutils-2.19/configure.ac +++ b/binutils-2.19/configure.ac @@ -165,7 +165,7 @@ host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib l # know that we are building the simulator. # binutils, gas and ld appear in that order because it makes sense to run # "make check" in that particular order. -# If --enable-gold is used, "gold" will replace "ld". +# If --enable-gold is used, "gold" may replace "ld". host_tools="byacc flex bison binutils gas ld fixincludes gcc sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" # libgcj represents the runtime libraries only used by gcj. @@ -294,37 +294,57 @@ case ${with_newlib} in esac # Handle --enable-gold. - -AC_ARG_ENABLE(gold, -[ --enable-gold use gold instead of ld], -ENABLE_GOLD=$enableval, -ENABLE_GOLD=no) -if test "${ENABLE_GOLD}" = "yes"; then - # Check for ELF target. - is_elf=no - case "${target}" in - *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ - | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ - | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2*) - case "${target}" in - *-*-linux*aout* | *-*-linux*oldld*) - ;; - *) - is_elf=yes - ;; - esac - esac - - if test "$is_elf" = "yes"; then - # Check for target supported by gold. +# --enable-gold Build only gold +# --disable-gold [default] Build only ld +# --enable-gold=both Build both gold and ld, ld is default +# --enable-gold=both/ld Same +# --enable-gold=both/gold Build both gold and ld, gold is default, ld is renamed ld.bfd + + AC_ARG_ENABLE(gold, +[[ --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]]]], + ENABLE_GOLD=$enableval, + ENABLE_GOLD=no) + case "${ENABLE_GOLD}" in + yes|both|both/gold|both/ld) + # Check for ELF target. + is_elf=no case "${target}" in - i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) - configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" - ;; + *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ + | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ + | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*) + case "${target}" in + *-*-linux*aout* | *-*-linux*oldld*) + ;; + *) + is_elf=yes + ;; + esac esac - fi -fi + if test "$is_elf" = "yes"; then + # Check for target supported by gold. + case "${target}" in + i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) + case "${ENABLE_GOLD}" in + both*) + configdirs="$configdirs gold" + ;; + *) + configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" + ;; + esac + ENABLE_GOLD=yes + ;; + esac + fi + ;; + no) + ;; + *) + AC_MSG_ERROR([invalid --enable-gold argument]) + ;; + esac + # Configure extra directories which are host specific case "${host}" in diff --git a/binutils-2.19/gold/Makefile.am b/binutils-2.19/gold/Makefile.am index e0665e0..df5e66c 100644 --- a/binutils-2.19/gold/Makefile.am +++ b/binutils-2.19/gold/Makefile.am @@ -178,12 +178,23 @@ check: libgold.a install-exec-local: ld-new$(EXEEXT) $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(tooldir)/bin - n=`echo ld | sed '$(transform)'`; \ + n=`echo $(installed_linker) | sed '$(transform)'`; \ $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(bindir)/$${n}$(EXEEXT); \ if test "$(bindir)" != "$(tooldir)/bin"; then \ - rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ - ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ + rm -f $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT) >/dev/null 2>/dev/null \ + || $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + fi; \ + if test "x$(install_as_default)" = "xyes"; then \ + ld=`echo ld | sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/$${ld}$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(bindir)/$${ld}$(EXEEXT) >/dev/null 2>/dev/null \ + || $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(bindir)/$${ld}$(EXEEXT); \ + if test "$(bindir)" != "$(tooldir)/bin"; then \ + rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ || $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + fi; \ fi # We want install to imply install-info as per GNU standards, despite diff --git a/binutils-2.19/gold/Makefile.in b/binutils-2.19/gold/Makefile.in index 29e1d1a..e9b28bc 100644 --- a/binutils-2.19/gold/Makefile.in +++ b/binutils-2.19/gold/Makefile.in @@ -305,7 +305,9 @@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ +install_as_default = @install_as_default@ install_sh = @install_sh@ +installed_linker = @installed_linker@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ @@ -1226,12 +1228,23 @@ check: libgold.a install-exec-local: ld-new$(EXEEXT) $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(tooldir)/bin - n=`echo ld | sed '$(transform)'`; \ + n=`echo $(installed_linker) | sed '$(transform)'`; \ $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(bindir)/$${n}$(EXEEXT); \ if test "$(bindir)" != "$(tooldir)/bin"; then \ - rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ - ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ + rm -f $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT) >/dev/null 2>/dev/null \ + || $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + fi; \ + if test "x$(install_as_default)" = "xyes"; then \ + ld=`echo ld | sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/$${ld}$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(bindir)/$${ld}$(EXEEXT) >/dev/null 2>/dev/null \ + || $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(bindir)/$${ld}$(EXEEXT); \ + if test "$(bindir)" != "$(tooldir)/bin"; then \ + rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$${n}$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ || $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + fi; \ fi # We want install to imply install-info as per GNU standards, despite diff --git a/binutils-2.19/gold/arm.cc b/binutils-2.19/gold/arm.cc index 8943fea..76f28be 100644 --- a/binutils-2.19/gold/arm.cc +++ b/binutils-2.19/gold/arm.cc @@ -1164,6 +1164,11 @@ class Arm_input_section : public Output_relaxed_input_section as_arm_input_section(Output_relaxed_input_section* poris) { return static_cast<Arm_input_section<big_endian>*>(poris); } + // Return the original size of the section. + uint32_t + original_size() const + { return this->original_size_; } + protected: // Write data to output file. void @@ -1175,7 +1180,7 @@ class Arm_input_section : public Output_relaxed_input_section { if (this->is_stub_table_owner()) return std::max(this->stub_table_->addralign(), - this->original_addralign_); + static_cast<uint64_t>(this->original_addralign_)); else return this->original_addralign_; } @@ -1197,8 +1202,8 @@ class Arm_input_section : public Output_relaxed_input_section if ((object == this->relobj()) && (shndx == this->shndx()) && (offset >= 0) - && (convert_types<uint64_t, section_offset_type>(offset) - <= this->original_size_)) + && (offset <= + convert_types<section_offset_type, uint32_t>(this->original_size_))) { *poutput = offset; return true; @@ -1213,9 +1218,9 @@ class Arm_input_section : public Output_relaxed_input_section Arm_input_section& operator=(const Arm_input_section&); // Address alignment of the original input section. - uint64_t original_addralign_; + uint32_t original_addralign_; // Section size of the original input section. - uint64_t original_size_; + uint32_t original_size_; // Stub table. Stub_table<big_endian>* stub_table_; }; @@ -1946,6 +1951,79 @@ class Arm_output_data_got : public Output_data_got<32, big_endian> std::vector<Static_reloc> static_relocs_; }; +// The ARM target has many relocation types with odd-sizes or incontigious +// bits. The default handling of relocatable relocation cannot process these +// relocations. So we have to extend the default code. + +template<bool big_endian, int sh_type, typename Classify_reloc> +class Arm_scan_relocatable_relocs : + public Default_scan_relocatable_relocs<sh_type, Classify_reloc> +{ + public: + // Return the strategy to use for a local symbol which is a section + // symbol, given the relocation type. + inline Relocatable_relocs::Reloc_strategy + local_section_strategy(unsigned int r_type, Relobj*) + { + if (sh_type == elfcpp::SHT_RELA) + return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA; + else + { + if (r_type == elfcpp::R_ARM_TARGET1 + || r_type == elfcpp::R_ARM_TARGET2) + { + const Target_arm<big_endian>* arm_target = + Target_arm<big_endian>::default_target(); + r_type = arm_target->get_real_reloc_type(r_type); + } + + switch(r_type) + { + // Relocations that write nothing. These exclude R_ARM_TARGET1 + // and R_ARM_TARGET2. + case elfcpp::R_ARM_NONE: + case elfcpp::R_ARM_V4BX: + case elfcpp::R_ARM_TLS_GOTDESC: + case elfcpp::R_ARM_TLS_CALL: + case elfcpp::R_ARM_TLS_DESCSEQ: + case elfcpp::R_ARM_THM_TLS_CALL: + case elfcpp::R_ARM_GOTRELAX: + case elfcpp::R_ARM_GNU_VTENTRY: + case elfcpp::R_ARM_GNU_VTINHERIT: + case elfcpp::R_ARM_THM_TLS_DESCSEQ16: + case elfcpp::R_ARM_THM_TLS_DESCSEQ32: + return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0; + // These should have been converted to something else above. + case elfcpp::R_ARM_TARGET1: + case elfcpp::R_ARM_TARGET2: + gold_unreachable(); + // Relocations that write full 32 bits. + case elfcpp::R_ARM_ABS32: + case elfcpp::R_ARM_REL32: + case elfcpp::R_ARM_SBREL32: + case elfcpp::R_ARM_GOTOFF32: + case elfcpp::R_ARM_BASE_PREL: + case elfcpp::R_ARM_GOT_BREL: + case elfcpp::R_ARM_BASE_ABS: + case elfcpp::R_ARM_ABS32_NOI: + case elfcpp::R_ARM_REL32_NOI: + case elfcpp::R_ARM_PLT32_ABS: + case elfcpp::R_ARM_GOT_ABS: + case elfcpp::R_ARM_GOT_PREL: + case elfcpp::R_ARM_TLS_GD32: + case elfcpp::R_ARM_TLS_LDM32: + case elfcpp::R_ARM_TLS_LDO32: + case elfcpp::R_ARM_TLS_IE32: + case elfcpp::R_ARM_TLS_LE32: + return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4; + default: + // For all other static relocations, return RELOC_SPECIAL. + return Relocatable_relocs::RELOC_SPECIAL; + } + } + } +}; + // Utilities for manipulating integers of up to 32-bits namespace utils @@ -2175,6 +2253,21 @@ class Target_arm : public Sized_target<32, big_endian> unsigned char* reloc_view, section_size_type reloc_view_size); + // Perform target-specific processing in a relocatable link. This is + // only used if we use the relocation strategy RELOC_SPECIAL. + void + relocate_special_relocatable(const Relocate_info<32, big_endian>* relinfo, + unsigned int sh_type, + const unsigned char* preloc_in, + size_t relnum, + Output_section* output_section, + off_t offset_in_output_section, + unsigned char* view, + typename elfcpp::Elf_types<32>::Elf_Addr + view_address, + section_size_type view_size, + unsigned char* preloc_out); + // Return whether SYM is defined by the ABI. bool do_is_defined_by_abi(Symbol* sym) const @@ -3706,6 +3799,7 @@ Arm_relocate_functions<big_endian>::arm_branch_common( Target_arm<big_endian>::default_target(); if (is_weakly_undefined_without_plt) { + gold_assert(!parameters->options().relocatable()); Valtype cond = val & 0xf0000000U; if (arm_target->may_use_arm_nop()) val = cond | 0x0320f000; @@ -3723,8 +3817,11 @@ Arm_relocate_functions<big_endian>::arm_branch_common( // to switch mode. bool may_use_blx = arm_target->may_use_blx(); Reloc_stub* stub = NULL; - if (utils::has_overflow<26>(branch_offset) - || ((thumb_bit != 0) && !(may_use_blx && r_type == elfcpp::R_ARM_CALL))) + + if (!parameters->options().relocatable() + && (utils::has_overflow<26>(branch_offset) + || ((thumb_bit != 0) + && !(may_use_blx && r_type == elfcpp::R_ARM_CALL)))) { Valtype unadjusted_branch_target = psymval->value(object, 0); @@ -3831,6 +3928,7 @@ Arm_relocate_functions<big_endian>::thumb_branch_common( Target_arm<big_endian>::default_target(); if (is_weakly_undefined_without_plt) { + gold_assert(!parameters->options().relocatable()); if (arm_target->may_use_thumb2_nop()) { elfcpp::Swap<16, big_endian>::writeval(wv, 0xf3af); @@ -3857,11 +3955,12 @@ Arm_relocate_functions<big_endian>::thumb_branch_common( // We need a stub if the branch offset is too large or if we need // to switch mode. bool thumb2 = arm_target->using_thumb2(); - if ((!thumb2 && utils::has_overflow<23>(branch_offset)) - || (thumb2 && utils::has_overflow<25>(branch_offset)) - || ((thumb_bit == 0) - && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx) - || r_type == elfcpp::R_ARM_THM_JUMP24))) + if (!parameters->options().relocatable() + && ((!thumb2 && utils::has_overflow<23>(branch_offset)) + || (thumb2 && utils::has_overflow<25>(branch_offset)) + || ((thumb_bit == 0) + && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx) + || r_type == elfcpp::R_ARM_THM_JUMP24)))) { Arm_address unadjusted_branch_target = psymval->value(object, 0); @@ -4895,8 +4994,10 @@ Arm_input_section<big_endian>::init() // Cache these to speed up size and alignment queries. It is too slow // to call section_addraglin and section_size every time. - this->original_addralign_ = relobj->section_addralign(shndx); - this->original_size_ = relobj->section_size(shndx); + this->original_addralign_ = + convert_types<uint32_t, uint64_t>(relobj->section_addralign(shndx)); + this->original_size_ = + convert_types<uint32_t, uint64_t>(relobj->section_size(shndx)); // We want to make this look like the original input section after // output sections are finalized. @@ -4931,21 +5032,15 @@ template<bool big_endian> void Arm_input_section<big_endian>::set_final_data_size() { - // If this owns a stub table, finalize its data size as well. + off_t off = convert_types<off_t, uint64_t>(this->original_size_); + if (this->is_stub_table_owner()) { - uint64_t address = this->address(); - - // The stub table comes after the original section contents. - address += this->original_size_; - address = align_address(address, this->stub_table_->addralign()); - off_t offset = this->offset() + (address - this->address()); - this->stub_table_->set_address_and_file_offset(address, offset); - address += this->stub_table_->data_size(); - gold_assert(address == this->address() + this->current_data_size()); + this->stub_table_->finalize_data_size(); + off = align_address(off, this->stub_table_->addralign()); + off += this->stub_table_->data_size(); } - - this->set_data_size(this->current_data_size()); + this->set_data_size(off); } // Reset address and file offset. @@ -5564,8 +5659,8 @@ Arm_output_section<big_endian>::fix_exidx_coverage( // Remove all input sections. uint64_t address = this->address(); - typedef std::list<Simple_input_section> Simple_input_section_list; - Simple_input_section_list input_sections; + typedef std::list<Output_section::Input_section> Input_section_list; + Input_section_list input_sections; this->reset_address_and_file_offset(); this->get_input_sections(address, std::string(""), &input_sections); @@ -5574,20 +5669,23 @@ Arm_output_section<big_endian>::fix_exidx_coverage( // Go through all the known input sections and record them. typedef Unordered_set<Section_id, Section_id_hash> Section_id_set; - Section_id_set known_input_sections; - for (Simple_input_section_list::const_iterator p = input_sections.begin(); + typedef Unordered_map<Section_id, const Output_section::Input_section*, + Section_id_hash> Text_to_exidx_map; + Text_to_exidx_map text_to_exidx_map; + for (Input_section_list::const_iterator p = input_sections.begin(); p != input_sections.end(); ++p) { // This should never happen. At this point, we should only see // plain EXIDX input sections. gold_assert(!p->is_relaxed_input_section()); - known_input_sections.insert(Section_id(p->relobj(), p->shndx())); + text_to_exidx_map[Section_id(p->relobj(), p->shndx())] = &(*p); } Arm_exidx_fixup exidx_fixup(this); // Go over the sorted text sections. + typedef Unordered_set<Section_id, Section_id_hash> Section_id_set; Section_id_set processed_input_sections; for (Text_section_list::const_iterator p = sorted_text_sections.begin(); p != sorted_text_sections.end(); @@ -5612,7 +5710,8 @@ Arm_output_section<big_endian>::fix_exidx_coverage( Relobj* exidx_relobj = exidx_input_section->relobj(); unsigned int exidx_shndx = exidx_input_section->shndx(); Section_id sid(exidx_relobj, exidx_shndx); - if (known_input_sections.find(sid) == known_input_sections.end()) + Text_to_exidx_map::const_iterator iter = text_to_exidx_map.find(sid); + if (iter == text_to_exidx_map.end()) { // This is odd. We have not seen this EXIDX input section before. // We cannot do fix-up. If we saw a SECTIONS clause in a script, @@ -5667,9 +5766,9 @@ Arm_output_section<big_endian>::fix_exidx_coverage( { // Just add back the EXIDX input section. gold_assert(section_offset_map == NULL); - Output_section::Simple_input_section sis(exidx_relobj, exidx_shndx); - this->add_simple_input_section(sis, exidx_input_section->size(), - exidx_input_section->addralign()); + const Output_section::Input_section* pis = iter->second; + gold_assert(pis->is_input_section()); + this->add_script_input_section(*pis); } processed_input_sections.insert(Section_id(exidx_relobj, exidx_shndx)); @@ -5679,7 +5778,7 @@ Arm_output_section<big_endian>::fix_exidx_coverage( exidx_fixup.add_exidx_cantunwind_as_needed(); // Remove any known EXIDX input sections that are not processed. - for (Simple_input_section_list::const_iterator p = input_sections.begin(); + for (Input_section_list::const_iterator p = input_sections.begin(); p != input_sections.end(); ++p) { @@ -5696,8 +5795,10 @@ Arm_output_section<big_endian>::fix_exidx_coverage( unsigned int text_shndx = exidx_input_section->link(); gold_assert(symtab->is_section_folded(p->relobj(), text_shndx)); - // Remove this from link. + // Remove this from link. We also need to recount the + // local symbols. p->relobj()->set_output_section(p->shndx(), NULL); + arm_relobj->set_output_local_symbol_count_needs_update(); } } @@ -8895,7 +8996,7 @@ Target_arm<big_endian>::scan_relocatable_relocs( { gold_assert(sh_type == elfcpp::SHT_REL); - typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL, + typedef Arm_scan_relocatable_relocs<big_endian, elfcpp::SHT_REL, Relocatable_size_for_reloc> Scan_relocatable_relocs; gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL, @@ -8947,6 +9048,291 @@ Target_arm<big_endian>::relocate_for_relocatable( reloc_view_size); } +// Perform target-specific processing in a relocatable link. This is +// only used if we use the relocation strategy RELOC_SPECIAL. + +template<bool big_endian> +void +Target_arm<big_endian>::relocate_special_relocatable( + const Relocate_info<32, big_endian>* relinfo, + unsigned int sh_type, + const unsigned char* preloc_in, + size_t relnum, + Output_section* output_section, + off_t offset_in_output_section, + unsigned char* view, + elfcpp::Elf_types<32>::Elf_Addr view_address, + section_size_type, + unsigned char* preloc_out) +{ + // We can only handle REL type relocation sections. + gold_assert(sh_type == elfcpp::SHT_REL); + + typedef typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc Reltype; + typedef typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc_write + Reltype_write; + const Arm_address invalid_address = static_cast<Arm_address>(0) - 1; + + const Arm_relobj<big_endian>* object = + Arm_relobj<big_endian>::as_arm_relobj(relinfo->object); + const unsigned int local_count = object->local_symbol_count(); + + Reltype reloc(preloc_in); + Reltype_write reloc_write(preloc_out); + + elfcpp::Elf_types<32>::Elf_WXword r_info = reloc.get_r_info(); + const unsigned int r_sym = elfcpp::elf_r_sym<32>(r_info); + const unsigned int r_type = elfcpp::elf_r_type<32>(r_info); + + const Arm_reloc_property* arp = + arm_reloc_property_table->get_implemented_static_reloc_property(r_type); + gold_assert(arp != NULL); + + // Get the new symbol index. + // We only use RELOC_SPECIAL strategy in local relocations. + gold_assert(r_sym < local_count); + + // We are adjusting a section symbol. We need to find + // the symbol table index of the section symbol for + // the output section corresponding to input section + // in which this symbol is defined. + bool is_ordinary; + unsigned int shndx = object->local_symbol_input_shndx(r_sym, &is_ordinary); + gold_assert(is_ordinary); + Output_section* os = object->output_section(shndx); + gold_assert(os != NULL); + gold_assert(os->needs_symtab_index()); + unsigned int new_symndx = os->symtab_index(); + + // Get the new offset--the location in the output section where + // this relocation should be applied. + + Arm_address offset = reloc.get_r_offset(); + Arm_address new_offset; + if (offset_in_output_section != invalid_address) + new_offset = offset + offset_in_output_section; + else + { + section_offset_type sot_offset = + convert_types<section_offset_type, Arm_address>(offset); + section_offset_type new_sot_offset = + output_section->output_offset(object, relinfo->data_shndx, + sot_offset); + gold_assert(new_sot_offset != -1); + new_offset = new_sot_offset; + } + + // In an object file, r_offset is an offset within the section. + // In an executable or dynamic object, generated by + // --emit-relocs, r_offset is an absolute address. + if (!parameters->options().relocatable()) + { + new_offset += view_address; + if (offset_in_output_section != invalid_address) + new_offset -= offset_in_output_section; + } + + reloc_write.put_r_offset(new_offset); + reloc_write.put_r_info(elfcpp::elf_r_info<32>(new_symndx, r_type)); + + // Handle the reloc addend. + // The relocation uses a section symbol in the input file. + // We are adjusting it to use a section symbol in the output + // file. The input section symbol refers to some address in + // the input section. We need the relocation in the output + // file to refer to that same address. This adjustment to + // the addend is the same calculation we use for a simple + // absolute relocation for the input section symbol. + + const Symbol_value<32>* psymval = object->local_symbol(r_sym); + + // Handle THUMB bit. + Symbol_value<32> symval; + Arm_address thumb_bit = + object->local_symbol_is_thumb_function(r_sym) ? 1 : 0; + if (thumb_bit != 0 + && arp->uses_thumb_bit() + && ((psymval->value(object, 0) & 1) != 0)) + { + Arm_address stripped_value = + psymval->value(object, 0) & ~static_cast<Arm_address>(1); + symval.set_output_value(stripped_value); + psymval = &symval; + } + + unsigned char* paddend = view + offset; + typename Arm_relocate_functions<big_endian>::Status reloc_status = + Arm_relocate_functions<big_endian>::STATUS_OKAY; + switch (r_type) + { + case elfcpp::R_ARM_ABS8: + reloc_status = Arm_relocate_functions<big_endian>::abs8(paddend, object, + psymval); + break; + + case elfcpp::R_ARM_ABS12: + reloc_status = Arm_relocate_functions<big_endian>::abs12(paddend, object, + psymval); + break; + + case elfcpp::R_ARM_ABS16: + reloc_status = Arm_relocate_functions<big_endian>::abs16(paddend, object, + psymval); + break; + + case elfcpp::R_ARM_THM_ABS5: + reloc_status = Arm_relocate_functions<big_endian>::thm_abs5(paddend, + object, + psymval); + break; + + case elfcpp::R_ARM_MOVW_ABS_NC: + case elfcpp::R_ARM_MOVW_PREL_NC: + case elfcpp::R_ARM_MOVW_BREL_NC: + case elfcpp::R_ARM_MOVW_BREL: + reloc_status = Arm_relocate_functions<big_endian>::movw( + paddend, object, psymval, 0, thumb_bit, arp->checks_overflow()); + break; + + case elfcpp::R_ARM_THM_MOVW_ABS_NC: + case elfcpp::R_ARM_THM_MOVW_PREL_NC: + case elfcpp::R_ARM_THM_MOVW_BREL_NC: + case elfcpp::R_ARM_THM_MOVW_BREL: + reloc_status = Arm_relocate_functions<big_endian>::thm_movw( + paddend, object, psymval, 0, thumb_bit, arp->checks_overflow()); + break; + + case elfcpp::R_ARM_THM_CALL: + case elfcpp::R_ARM_THM_XPC22: + case elfcpp::R_ARM_THM_JUMP24: + reloc_status = + Arm_relocate_functions<big_endian>::thumb_branch_common( + r_type, relinfo, paddend, NULL, object, 0, psymval, 0, thumb_bit, + false); + break; + + case elfcpp::R_ARM_PLT32: + case elfcpp::R_ARM_CALL: + case elfcpp::R_ARM_JUMP24: + case elfcpp::R_ARM_XPC25: + reloc_status = + Arm_relocate_functions<big_endian>::arm_branch_common( + r_type, relinfo, paddend, NULL, object, 0, psymval, 0, thumb_bit, + false); + break; + + case elfcpp::R_ARM_THM_JUMP19: + reloc_status = + Arm_relocate_functions<big_endian>::thm_jump19(paddend, object, + psymval, 0, thumb_bit); + break; + + case elfcpp::R_ARM_THM_JUMP6: + reloc_status = + Arm_relocate_functions<big_endian>::thm_jump6(paddend, object, psymval, + 0); + break; + + case elfcpp::R_ARM_THM_JUMP8: + reloc_status = + Arm_relocate_functions<big_endian>::thm_jump8(paddend, object, psymval, + 0); + break; + + case elfcpp::R_ARM_THM_JUMP11: + reloc_status = + Arm_relocate_functions<big_endian>::thm_jump11(paddend, object, psymval, + 0); + break; + + case elfcpp::R_ARM_PREL31: + reloc_status = + Arm_relocate_functions<big_endian>::prel31(paddend, object, psymval, 0, + thumb_bit); + break; + + case elfcpp::R_ARM_THM_PC8: + reloc_status = + Arm_relocate_functions<big_endian>::thm_pc8(paddend, object, psymval, + 0); + break; + + case elfcpp::R_ARM_THM_PC12: + reloc_status = + Arm_relocate_functions<big_endian>::thm_pc12(paddend, object, psymval, + 0); + break; + + case elfcpp::R_ARM_THM_ALU_PREL_11_0: + reloc_status = + Arm_relocate_functions<big_endian>::thm_alu11(paddend, object, psymval, + 0, thumb_bit); + break; + + // These relocation truncate relocation results so we cannot handle them + // in a relocatable link. + case elfcpp::R_ARM_MOVT_ABS: + case elfcpp::R_ARM_THM_MOVT_ABS: + case elfcpp::R_ARM_MOVT_PREL: + case elfcpp::R_ARM_MOVT_BREL: + case elfcpp::R_ARM_THM_MOVT_PREL: + case elfcpp::R_ARM_THM_MOVT_BREL: + case elfcpp::R_ARM_ALU_PC_G0_NC: + case elfcpp::R_ARM_ALU_PC_G0: + case elfcpp::R_ARM_ALU_PC_G1_NC: + case elfcpp::R_ARM_ALU_PC_G1: + case elfcpp::R_ARM_ALU_PC_G2: + case elfcpp::R_ARM_ALU_SB_G0_NC: + case elfcpp::R_ARM_ALU_SB_G0: + case elfcpp::R_ARM_ALU_SB_G1_NC: + case elfcpp::R_ARM_ALU_SB_G1: + case elfcpp::R_ARM_ALU_SB_G2: + case elfcpp::R_ARM_LDR_PC_G0: + case elfcpp::R_ARM_LDR_PC_G1: + case elfcpp::R_ARM_LDR_PC_G2: + case elfcpp::R_ARM_LDR_SB_G0: + case elfcpp::R_ARM_LDR_SB_G1: + case elfcpp::R_ARM_LDR_SB_G2: + case elfcpp::R_ARM_LDRS_PC_G0: + case elfcpp::R_ARM_LDRS_PC_G1: + case elfcpp::R_ARM_LDRS_PC_G2: + case elfcpp::R_ARM_LDRS_SB_G0: + case elfcpp::R_ARM_LDRS_SB_G1: + case elfcpp::R_ARM_LDRS_SB_G2: + case elfcpp::R_ARM_LDC_PC_G0: + case elfcpp::R_ARM_LDC_PC_G1: + case elfcpp::R_ARM_LDC_PC_G2: + case elfcpp::R_ARM_LDC_SB_G0: + case elfcpp::R_ARM_LDC_SB_G1: + case elfcpp::R_ARM_LDC_SB_G2: + gold_error(_("cannot handle %s in a relocatable link"), + arp->name().c_str()); + break; + + default: + gold_unreachable(); + } + + // Report any errors. + switch (reloc_status) + { + case Arm_relocate_functions<big_endian>::STATUS_OKAY: + break; + case Arm_relocate_functions<big_endian>::STATUS_OVERFLOW: + gold_error_at_location(relinfo, relnum, reloc.get_r_offset(), + _("relocation overflow in %s"), + arp->name().c_str()); + break; + case Arm_relocate_functions<big_endian>::STATUS_BAD_RELOC: + gold_error_at_location(relinfo, relnum, reloc.get_r_offset(), + _("unexpected opcode while processing relocation %s"), + arp->name().c_str()); + break; + default: + gold_unreachable(); + } +} + // Return the value to use for a dynamic symbol which requires special // treatment. This is how we support equality comparisons of function // pointers across shared library boundaries, as described in the @@ -10362,6 +10748,7 @@ Target_arm<big_endian>::do_relax( // If this is the first pass, we need to group input sections into // stub groups. bool done_exidx_fixup = false; + typedef typename Stub_table_list::iterator Stub_table_iterator; if (pass == 1) { // Determine the stub group size. The group size is the absolute @@ -10410,13 +10797,27 @@ Target_arm<big_endian>::do_relax( done_exidx_fixup = true; } } + else + { + // If this is not the first pass, addresses and file offsets have + // been reset at this point, set them here. + for (Stub_table_iterator sp = this->stub_tables_.begin(); + sp != this->stub_tables_.end(); + ++sp) + { + Arm_input_section<big_endian>* owner = (*sp)->owner(); + off_t off = align_address(owner->original_size(), + (*sp)->addralign()); + (*sp)->set_address_and_file_offset(owner->address() + off, + owner->offset() + off); + } + } // The Cortex-A8 stubs are sensitive to layout of code sections. At the // beginning of each relaxation pass, just blow away all the stubs. // Alternatively, we could selectively remove only the stubs and reloc // information for code sections that have moved since the last pass. // That would require more book-keeping. - typedef typename Stub_table_list::iterator Stub_table_iterator; if (this->fix_cortex_a8_) { // Clear all Cortex-A8 reloc information. @@ -10793,13 +11194,11 @@ Target_arm<big_endian>::apply_cortex_a8_workaround( switch (stub->stub_template()->type()) { case arm_stub_a8_veneer_b_cond: - gold_assert(!utils::has_overflow<21>(branch_offset)); - upper_insn = RelocFuncs::thumb32_cond_branch_upper(upper_insn, - branch_offset); - lower_insn = RelocFuncs::thumb32_cond_branch_lower(lower_insn, - branch_offset); - break; - + // For a conditional branch, we re-write it to be a uncondition + // branch to the stub. We use the THUMB-2 encoding here. + upper_insn = 0xf000U; + lower_insn = 0xb800U; + // Fall through case arm_stub_a8_veneer_b: case arm_stub_a8_veneer_bl: case arm_stub_a8_veneer_blx: diff --git a/binutils-2.19/gold/configure b/binutils-2.19/gold/configure index 9fd198f..1a86978 100644 --- a/binutils-2.19/gold/configure +++ b/binutils-2.19/gold/configure @@ -682,6 +682,8 @@ PLUGINS_FALSE PLUGINS_TRUE THREADS_FALSE THREADS_TRUE +installed_linker +install_as_default am__untar am__tar AMTAR @@ -759,6 +761,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking with_sysroot +enable_gold enable_threads enable_plugins enable_targets @@ -1403,6 +1406,7 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]] --enable-threads multi-threaded linking --enable-plugins linker plugins --enable-targets alternative target configurations @@ -3227,6 +3231,33 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# Check whether --enable-gold was given. +if test "${enable_gold+set}" = set; then : + enableval=$enable_gold; case "${enableval}" in + yes) + install_as_default=gold + installed_linker=ld + ;; + both/gold) + install_as_default=yes + installed_linker=ld.gold + ;; + both|both/ld) + install_as_default=no + installed_linker=ld.gold + ;; + *) + as_fn_error "invalid --enable-gold argument" "$LINENO" 5 + ;; + esac +else + install_as_default=gold + installed_linker=ld +fi + + + + # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; case "${enableval}" in diff --git a/binutils-2.19/gold/configure.ac b/binutils-2.19/gold/configure.ac index f184d4b..e560117 100644 --- a/binutils-2.19/gold/configure.ac +++ b/binutils-2.19/gold/configure.ac @@ -38,6 +38,33 @@ AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT, "$sysroot", AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT_RELOCATABLE, $sysroot_relocatable, [Whether the system root can be relocated]) +dnl "install_as_default" is true if the linker to be installed as the +dnl default linker, ld. +dnl "installed_linker" is the installed gold linker name. +AC_ARG_ENABLE(gold, +[[ --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]]]], +[case "${enableval}" in + yes) + install_as_default=gold + installed_linker=ld + ;; + both/gold) + install_as_default=yes + installed_linker=ld.gold + ;; + both|both/ld) + install_as_default=no + installed_linker=ld.gold + ;; + *) + AC_MSG_ERROR([invalid --enable-gold argument]) + ;; + esac], +[install_as_default=gold + installed_linker=ld]) +AC_SUBST(install_as_default) +AC_SUBST(installed_linker) + dnl For now threads are a configure time option. AC_ARG_ENABLE([threads], [ --enable-threads multi-threaded linking], diff --git a/binutils-2.19/gold/gold.cc b/binutils-2.19/gold/gold.cc index 39c2ce7..bf81321 100644 --- a/binutils-2.19/gold/gold.cc +++ b/binutils-2.19/gold/gold.cc @@ -276,6 +276,16 @@ queue_middle_gc_tasks(const General_options& options, next_blocker)); this_blocker = next_blocker; } + + // If we are given only archives in input, we have no regular + // objects and THIS_BLOCKER is NULL here. Create a dummy + // blocker here so that we can run the middle tasks immediately. + if (this_blocker == NULL) + { + gold_assert(input_objects->number_of_relobjs() == 0); + this_blocker = new Task_token(true); + } + workqueue->queue(new Task_function(new Middle_runner(options, input_objects, symtab, diff --git a/binutils-2.19/gold/merge.cc b/binutils-2.19/gold/merge.cc index e2b6eef..6e44ddd 100644 --- a/binutils-2.19/gold/merge.cc +++ b/binutils-2.19/gold/merge.cc @@ -304,6 +304,26 @@ Output_merge_base::do_is_merge_section_for(const Relobj* object, return this->merge_map_.is_merge_section_for(object, shndx); } +// Record a merged input section for script processing. + +void +Output_merge_base::record_input_section(Relobj* relobj, unsigned int shndx) +{ + gold_assert(this->keeps_input_sections_ && relobj != NULL); + // If this is the first input section, record it. We need do this because + // this->input_sections_ is unordered. + if (this->first_relobj_ == NULL) + { + this->first_relobj_ = relobj; + this->first_shndx_ = shndx; + } + + std::pair<Input_sections::iterator, bool> result = + this->input_sections_.insert(Section_id(relobj, shndx)); + // We should insert a merge section once only. + gold_assert(result.second); +} + // Class Output_merge_data. // Compute the hash code for a fixed-size constant. @@ -414,6 +434,10 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx) this->add_mapping(object, shndx, i, entsize, k); } + // For script processing, we keep the input sections. + if (this->keeps_input_sections()) + record_input_section(object, shndx); + return true; } @@ -517,6 +541,10 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object, this->input_count_ += count; + // For script processing, we keep the input sections. + if (this->keeps_input_sections()) + record_input_section(object, shndx); + return true; } diff --git a/binutils-2.19/gold/merge.h b/binutils-2.19/gold/merge.h index 345b115..c2d305b 100644 --- a/binutils-2.19/gold/merge.h +++ b/binutils-2.19/gold/merge.h @@ -216,7 +216,9 @@ class Output_merge_base : public Output_section_data { public: Output_merge_base(uint64_t entsize, uint64_t addralign) - : Output_section_data(addralign), merge_map_(), entsize_(entsize) + : Output_section_data(addralign), merge_map_(), entsize_(entsize), + keeps_input_sections_(false), first_relobj_(NULL), first_shndx_(-1), + input_sections_() { } // Return the entry size. @@ -230,6 +232,52 @@ class Output_merge_base : public Output_section_data is_string() { return this->do_is_string(); } + // Whether this keeps input sections. + bool + keeps_input_sections() const + { return this->keeps_input_sections_; } + + // Set the keeps-input-sections flag. This is virtual so that sub-classes + // can perform additional checks. + void + set_keeps_input_sections() + { this->do_set_keeps_input_sections(); } + + // Return the object of the first merged input section. This used + // for script processing. This is NULL if merge section is empty. + Relobj* + first_relobj() const + { return this->first_relobj_; } + + // Return the section index of the first merged input section. This + // is used for script processing. This is valid only if merge section + // is not valid. + unsigned int + first_shndx() const + { + gold_assert(this->first_relobj_ != NULL); + return this->first_shndx_; + } + + // Set of merged input sections. + typedef Unordered_set<Section_id, Section_id_hash> Input_sections; + + // Beginning of merged input sections. + Input_sections::const_iterator + input_sections_begin() const + { + gold_assert(this->keeps_input_sections_); + return this->input_sections_.begin(); + } + + // Beginning of merged input sections. + Input_sections::const_iterator + input_sections_end() const + { + gold_assert(this->keeps_input_sections_); + return this->input_sections_.end(); + } + protected: // Return the output offset for an input offset. bool @@ -257,6 +305,15 @@ class Output_merge_base : public Output_section_data do_is_string() { return false; } + // This may be overridden by the child class. + virtual void + do_set_keeps_input_sections() + { this->keeps_input_sections_ = true; } + + // Record the merged input section for script processing. + void + record_input_section(Relobj* relobj, unsigned int shndx); + private: // A mapping from input object/section/offset to offset in output // section. @@ -264,6 +321,15 @@ class Output_merge_base : public Output_section_data // The entry size. For fixed-size constants, this is the size of // the constants. For strings, this is the size of a character. uint64_t entsize_; + // Whether we keep input sections. + bool keeps_input_sections_; + // Object of the first merged input section. We use this for script + // processing. + Relobj* first_relobj_; + // Section index of the first merged input section. + unsigned int first_shndx_; + // Input sections. We only keep them is keeps_input_sections_ is true. + Input_sections input_sections_; }; // Handle SHF_MERGE sections with fixed-size constant data. @@ -303,6 +369,14 @@ class Output_merge_data : public Output_merge_base void do_print_merge_stats(const char* section_name); + // Set keeps-input-sections flag. + void + do_set_keeps_input_sections() + { + gold_assert(this->input_count_ == 0); + Output_merge_base::do_set_keeps_input_sections(); + } + private: // We build a hash table of the fixed-size constants. Each constant // is stored as a pointer into the section data we are accumulating. @@ -440,6 +514,14 @@ class Output_merge_string : public Output_merge_base do_is_string() { return true; } + // Set keeps-input-sections flag. + void + do_set_keeps_input_sections() + { + gold_assert(this->input_count_ == 0); + Output_merge_base::do_set_keeps_input_sections(); + } + private: // The name of the string type, for stats. const char* diff --git a/binutils-2.19/gold/object.cc b/binutils-2.19/gold/object.cc index 73bf370..02366c0 100644 --- a/binutils-2.19/gold/object.cc +++ b/binutils-2.19/gold/object.cc @@ -1751,7 +1751,12 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, const Output_section_data* posd = os->find_relaxed_input_section(this, shndx); if (posd != NULL) - lv.set_output_value(posd->address()); + { + Address relocatable_link_adjustment = + relocatable ? os->address() : 0; + lv.set_output_value(posd->address() + - relocatable_link_adjustment); + } else lv.set_output_value(os->address()); } @@ -1759,9 +1764,14 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, { // We have to consider the addend to determine the // value to use in a relocation. START is the start - // of this input section. + // of this input section. If we are doing a relocatable + // link, use offset from start output section instead of + // address. + Address adjusted_start = + relocatable ? start - os->address() : start; Merged_symbol_value<size>* msv = - new Merged_symbol_value<size>(lv.input_value(), start); + new Merged_symbol_value<size>(lv.input_value(), + adjusted_start); lv.set_merged_symbol_value(msv); } } diff --git a/binutils-2.19/gold/output.cc b/binutils-2.19/gold/output.cc index ff43d53..dbdad78 100644 --- a/binutils-2.19/gold/output.cc +++ b/binutils-2.19/gold/output.cc @@ -1745,6 +1745,42 @@ Output_section::Input_section::data_size() const return this->u2_.posd->data_size(); } +// Return the object for an input section. + +Relobj* +Output_section::Input_section::relobj() const +{ + if (this->is_input_section()) + return this->u2_.object; + else if (this->is_merge_section()) + { + gold_assert(this->u2_.pomb->first_relobj() != NULL); + return this->u2_.pomb->first_relobj(); + } + else if (this->is_relaxed_input_section()) + return this->u2_.poris->relobj(); + else + gold_unreachable(); +} + +// Return the input section index for an input section. + +unsigned int +Output_section::Input_section::shndx() const +{ + if (this->is_input_section()) + return this->shndx_; + else if (this->is_merge_section()) + { + gold_assert(this->u2_.pomb->first_relobj() != NULL); + return this->u2_.pomb->first_shndx(); + } + else if (this->is_relaxed_input_section()) + return this->u2_.poris->shndx(); + else + gold_unreachable(); +} + // Set the address and file offset. void @@ -1910,10 +1946,7 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type, is_noload_(false), tls_offset_(0), checkpoint_(NULL), - merge_section_map_(), - merge_section_by_properties_map_(), - relaxed_input_section_map_(), - is_relaxed_input_section_map_valid_(true) + lookup_maps_(new Output_section_lookup_maps) { // An unallocated section has no address. Forcing this means that // we don't need special treatment for symbols defined in debug @@ -1997,8 +2030,12 @@ Output_section::add_input_section(Sized_relobj<size, big_endian>* object, && reloc_shndx == 0 && shdr.get_sh_size() > 0) { - if (this->add_merge_input_section(object, shndx, sh_flags, - entsize, addralign)) + // Keep information about merged input sections for rebuilding fast + // lookup maps if we have sections-script or we do relaxation. + bool keeps_input_sections = + have_sections_script || parameters->target().may_relax(); + if (this->add_merge_input_section(object, shndx, sh_flags, entsize, + addralign, keeps_input_sections)) { // Tell the relocation routines that they need to call the // output_offset method to determine the final address. @@ -2088,11 +2125,9 @@ Output_section::add_relaxed_input_section(Output_relaxed_input_section* poris) { Input_section inp(poris); this->add_output_section_data(&inp); - if (this->is_relaxed_input_section_map_valid_) - { - Const_section_id csid(poris->relobj(), poris->shndx()); - this->relaxed_input_section_map_[csid] = poris; - } + if (this->lookup_maps_->is_valid()) + this->lookup_maps_->add_relaxed_input_section(poris->relobj(), + poris->shndx(), poris); // For a relaxed section, we use the current data size. Linker scripts // get all the input sections, including relaxed one from an output @@ -2138,7 +2173,8 @@ Output_section::add_output_merge_section(Output_section_data* posd, bool Output_section::add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags, uint64_t entsize, - uint64_t addralign) + uint64_t addralign, + bool keeps_input_sections) { bool is_string = (flags & elfcpp::SHF_STRINGS) != 0; @@ -2151,13 +2187,15 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx, gold_assert(this->checkpoint_ == NULL); // Look up merge sections by required properties. - Output_merge_base* pomb; + // Currently, we only invalidate the lookup maps in script processing + // and relaxation. We should not have done either when we reach here. + // So we assume that the lookup maps are valid to simply code. + gold_assert(this->lookup_maps_->is_valid()); Merge_section_properties msp(is_string, entsize, addralign); - Merge_section_by_properties_map::const_iterator p = - this->merge_section_by_properties_map_.find(msp); - if (p != this->merge_section_by_properties_map_.end()) + Output_merge_base* pomb = this->lookup_maps_->find_merge_section(msp); + bool is_new = false; + if (pomb != NULL) { - pomb = p->second; gold_assert(pomb->is_string() == is_string && pomb->entsize() == entsize && pomb->addralign() == addralign); @@ -2184,22 +2222,36 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx, return false; } } - // Add new merge section to this output section and link merge - // section properties to new merge section in map. - this->add_output_merge_section(pomb, is_string, entsize); - this->merge_section_by_properties_map_[msp] = pomb; + // If we need to do script processing or relaxation, we need to keep + // the original input sections to rebuild the fast lookup maps. + if (keeps_input_sections) + pomb->set_keeps_input_sections(); + is_new = true; } if (pomb->add_input_section(object, shndx)) { + // Add new merge section to this output section and link merge + // section properties to new merge section in map. + if (is_new) + { + this->add_output_merge_section(pomb, is_string, entsize); + this->lookup_maps_->add_merge_section(msp, pomb); + } + // Add input section to new merge section and link input section to new // merge section in map. - Const_section_id csid(object, shndx); - this->merge_section_map_[csid] = pomb; + this->lookup_maps_->add_merge_input_section(object, shndx, pomb); return true; } else - return false; + { + // If add_input_section failed, delete new merge section to avoid + // exporting empty merge sections in Output_section::get_input_section. + if (is_new) + delete pomb; + return false; + } } // Build a relaxation map to speed up relaxation of existing input sections. @@ -2294,12 +2346,12 @@ Output_section::convert_input_sections_to_relaxed_sections( &this->input_sections_); // Update fast look-up map. - if (this->is_relaxed_input_section_map_valid_) + if (this->lookup_maps_->is_valid()) for (size_t i = 0; i < relaxed_sections.size(); ++i) { Output_relaxed_input_section* poris = relaxed_sections[i]; - Const_section_id csid(poris->relobj(), poris->shndx()); - this->relaxed_input_section_map_[csid] = poris; + this->lookup_maps_->add_relaxed_input_section(poris->relobj(), + poris->shndx(), poris); } } @@ -2344,17 +2396,47 @@ Output_section_data* Output_section::find_merge_section(const Relobj* object, unsigned int shndx) const { - Const_section_id csid(object, shndx); - Output_section_data_by_input_section_map::const_iterator p = - this->merge_section_map_.find(csid); - if (p != this->merge_section_map_.end()) + if (!this->lookup_maps_->is_valid()) + this->build_lookup_maps(); + return this->lookup_maps_->find_merge_section(object, shndx); +} + +// Build the lookup maps for merge and relaxed sections. This is needs +// to be declared as a const methods so that it is callable with a const +// Output_section pointer. The method only updates states of the maps. + +void +Output_section::build_lookup_maps() const +{ + this->lookup_maps_->clear(); + for (Input_section_list::const_iterator p = this->input_sections_.begin(); + p != this->input_sections_.end(); + ++p) { - Output_section_data* posd = p->second; - gold_assert(posd->is_merge_section_for(object, shndx)); - return posd; + if (p->is_merge_section()) + { + Output_merge_base* pomb = p->output_merge_base(); + Merge_section_properties msp(pomb->is_string(), pomb->entsize(), + pomb->addralign()); + this->lookup_maps_->add_merge_section(msp, pomb); + for (Output_merge_base::Input_sections::const_iterator is = + pomb->input_sections_begin(); + is != pomb->input_sections_end(); + ++is) + { + const Const_section_id& csid = *is; + this->lookup_maps_->add_merge_input_section(csid.first, + csid.second, pomb); + } + + } + else if (p->is_relaxed_input_section()) + { + Output_relaxed_input_section* poris = p->relaxed_input_section(); + this->lookup_maps_->add_relaxed_input_section(poris->relobj(), + poris->shndx(), poris); + } } - else - return NULL; } // Find an relaxed input section corresponding to an input section @@ -2364,31 +2446,9 @@ const Output_relaxed_input_section* Output_section::find_relaxed_input_section(const Relobj* object, unsigned int shndx) const { - // Be careful that the map may not be valid due to input section export - // to scripts or a check-point restore. - if (!this->is_relaxed_input_section_map_valid_) - { - // Rebuild the map as needed. - this->relaxed_input_section_map_.clear(); - for (Input_section_list::const_iterator p = this->input_sections_.begin(); - p != this->input_sections_.end(); - ++p) - if (p->is_relaxed_input_section()) - { - Const_section_id csid(p->relobj(), p->shndx()); - this->relaxed_input_section_map_[csid] = - p->relaxed_input_section(); - } - this->is_relaxed_input_section_map_valid_ = true; - } - - Const_section_id csid(object, shndx); - Output_relaxed_input_section_by_input_section_map::const_iterator p = - this->relaxed_input_section_map_.find(csid); - if (p != this->relaxed_input_section_map_.end()) - return p->second; - else - return NULL; + if (!this->lookup_maps_->is_valid()) + this->build_lookup_maps(); + return this->lookup_maps_->find_relaxed_input_section(object, shndx); } // Given an address OFFSET relative to the start of input section @@ -3042,14 +3102,14 @@ uint64_t Output_section::get_input_sections( uint64_t address, const std::string& fill, - std::list<Simple_input_section>* input_sections) + std::list<Input_section>* input_sections) { if (this->checkpoint_ != NULL && !this->checkpoint_->input_sections_saved()) this->checkpoint_->save_input_sections(); - // Invalidate the relaxed input section map. - this->is_relaxed_input_section_map_valid_ = false; + // Invalidate fast look-up maps. + this->lookup_maps_->invalidate(); uint64_t orig_address = address; @@ -3060,12 +3120,10 @@ Output_section::get_input_sections( p != this->input_sections_.end(); ++p) { - if (p->is_input_section()) - input_sections->push_back(Simple_input_section(p->relobj(), - p->shndx())); - else if (p->is_relaxed_input_section()) - input_sections->push_back( - Simple_input_section(p->relaxed_input_section())); + if (p->is_input_section() + || p->is_relaxed_input_section() + || p->is_merge_section()) + input_sections->push_back(*p); else { uint64_t aligned_address = align_address(address, p->addralign()); @@ -3100,13 +3158,16 @@ Output_section::get_input_sections( return data_size; } -// Add an simple input section. +// Add a script input section. SIS is an Output_section::Input_section, +// which can be either a plain input section or a special input section like +// a relaxed input section. For a special input section, its size must be +// finalized. void -Output_section::add_simple_input_section(const Simple_input_section& sis, - off_t data_size, - uint64_t addralign) +Output_section::add_script_input_section(const Input_section& sis) { + uint64_t data_size = sis.data_size(); + uint64_t addralign = sis.addralign(); if (addralign > this->addralign_) this->addralign_ = addralign; @@ -3117,11 +3178,31 @@ Output_section::add_simple_input_section(const Simple_input_section& sis, this->set_current_data_size_for_child(aligned_offset_in_section + data_size); - Input_section is = - (sis.is_relaxed_input_section() - ? Input_section(sis.relaxed_input_section()) - : Input_section(sis.relobj(), sis.shndx(), data_size, addralign)); - this->input_sections_.push_back(is); + this->input_sections_.push_back(sis); + + // Update fast lookup maps if necessary. + if (this->lookup_maps_->is_valid()) + { + if (sis.is_merge_section()) + { + Output_merge_base* pomb = sis.output_merge_base(); + Merge_section_properties msp(pomb->is_string(), pomb->entsize(), + pomb->addralign()); + this->lookup_maps_->add_merge_section(msp, pomb); + for (Output_merge_base::Input_sections::const_iterator p = + pomb->input_sections_begin(); + p != pomb->input_sections_end(); + ++p) + this->lookup_maps_->add_merge_input_section(p->first, p->second, + pomb); + } + else if (sis.is_relaxed_input_section()) + { + Output_relaxed_input_section* poris = sis.relaxed_input_section(); + this->lookup_maps_->add_relaxed_input_section(poris->relobj(), + poris->shndx(), poris); + } + } } // Save states for relaxation. @@ -3147,9 +3228,9 @@ Output_section::discard_states() this->checkpoint_ = NULL; gold_assert(this->fills_.empty()); - // Simply invalidate the relaxed input section map since we do not keep - // track of it. - this->is_relaxed_input_section_map_valid_ = false; + // Simply invalidate the fast lookup maps since we do not keep + // track of them. + this->lookup_maps_->invalidate(); } void @@ -3181,9 +3262,9 @@ Output_section::restore_states() this->attached_input_sections_are_sorted_ = checkpoint->attached_input_sections_are_sorted(); - // Simply invalidate the relaxed input section map since we do not keep - // track of it. - this->is_relaxed_input_section_map_valid_ = false; + // Simply invalidate the fast lookup maps since we do not keep + // track of them. + this->lookup_maps_->invalidate(); } // Update the section offsets of input sections in this. This is required if diff --git a/binutils-2.19/gold/output.h b/binutils-2.19/gold/output.h index 8088565..da321b6 100644 --- a/binutils-2.19/gold/output.h +++ b/binutils-2.19/gold/output.h @@ -2314,6 +2314,188 @@ class Output_relaxed_input_section : public Output_section_data_build unsigned int shndx_; }; +// This class describes properties of merge data sections. It is used +// as a key type for maps. +class Merge_section_properties +{ + public: + Merge_section_properties(bool is_string, uint64_t entsize, + uint64_t addralign) + : is_string_(is_string), entsize_(entsize), addralign_(addralign) + { } + + // Whether this equals to another Merge_section_properties MSP. + bool + eq(const Merge_section_properties& msp) const + { + return ((this->is_string_ == msp.is_string_) + && (this->entsize_ == msp.entsize_) + && (this->addralign_ == msp.addralign_)); + } + + // Compute a hash value for this using 64-bit FNV-1a hash. + size_t + hash_value() const + { + uint64_t h = 14695981039346656037ULL; // FNV offset basis. + uint64_t prime = 1099511628211ULL; + h = (h ^ static_cast<uint64_t>(this->is_string_)) * prime; + h = (h ^ static_cast<uint64_t>(this->entsize_)) * prime; + h = (h ^ static_cast<uint64_t>(this->addralign_)) * prime; + return h; + } + + // Functors for associative containers. + struct equal_to + { + bool + operator()(const Merge_section_properties& msp1, + const Merge_section_properties& msp2) const + { return msp1.eq(msp2); } + }; + + struct hash + { + size_t + operator()(const Merge_section_properties& msp) const + { return msp.hash_value(); } + }; + + private: + // Whether this merge data section is for strings. + bool is_string_; + // Entsize of this merge data section. + uint64_t entsize_; + // Address alignment. + uint64_t addralign_; +}; + +// This class is used to speed up look up of special input sections in an +// Output_section. + +class Output_section_lookup_maps +{ + public: + Output_section_lookup_maps() + : is_valid_(true), merge_sections_by_properties_(), + merge_sections_by_id_(), relaxed_input_sections_by_id_() + { } + + // Whether the maps are valid. + bool + is_valid() const + { return this->is_valid_; } + + // Invalidate the maps. + void + invalidate() + { this->is_valid_ = false; } + + // Clear the maps. + void + clear() + { + this->merge_sections_by_properties_.clear(); + this->merge_sections_by_id_.clear(); + this->relaxed_input_sections_by_id_.clear(); + // A cleared map is valid. + this->is_valid_ = true; + } + + // Find a merge section by merge section properties. Return NULL if none + // is found. + Output_merge_base* + find_merge_section(const Merge_section_properties& msp) const + { + gold_assert(this->is_valid_); + Merge_sections_by_properties::const_iterator p = + this->merge_sections_by_properties_.find(msp); + return p != this->merge_sections_by_properties_.end() ? p->second : NULL; + } + + // Find a merge section by section ID of a merge input section. Return NULL + // if none is found. + Output_merge_base* + find_merge_section(const Object* object, unsigned int shndx) const + { + gold_assert(this->is_valid_); + Merge_sections_by_id::const_iterator p = + this->merge_sections_by_id_.find(Const_section_id(object, shndx)); + return p != this->merge_sections_by_id_.end() ? p->second : NULL; + } + + // Add a merge section pointed by POMB with properties MSP. + void + add_merge_section(const Merge_section_properties& msp, + Output_merge_base* pomb) + { + std::pair<Merge_section_properties, Output_merge_base*> value(msp, pomb); + std::pair<Merge_sections_by_properties::iterator, bool> result = + this->merge_sections_by_properties_.insert(value); + gold_assert(value.second); + } + + // Add a mapping from a merged input section in OBJECT with index SHNDX + // to a merge output section pointed by POMB. + void + add_merge_input_section(const Object* object, unsigned int shndx, + Output_merge_base* pomb) + { + Const_section_id csid(object, shndx); + std::pair<Const_section_id, Output_merge_base*> value(csid, pomb); + std::pair<Merge_sections_by_id::iterator, bool> result = + this->merge_sections_by_id_.insert(value); + gold_assert(value.second); + } + + // Find a relaxed input section of OBJECT with index SHNDX. + Output_relaxed_input_section* + find_relaxed_input_section(const Object* object, unsigned int shndx) const + { + gold_assert(this->is_valid_); + Relaxed_input_sections_by_id::const_iterator p = + this->relaxed_input_sections_by_id_.find(Const_section_id(object, shndx)); + return p != this->relaxed_input_sections_by_id_.end() ? p->second : NULL; + } + + // Add a relaxed input section pointed by POMB and whose original input + // section is in OBJECT with index SHNDX. + void + add_relaxed_input_section(const Relobj* relobj, unsigned int shndx, + Output_relaxed_input_section* poris) + { + Const_section_id csid(relobj, shndx); + std::pair<Const_section_id, Output_relaxed_input_section*> + value(csid, poris); + std::pair<Relaxed_input_sections_by_id::iterator, bool> result = + this->relaxed_input_sections_by_id_.insert(value); + gold_assert(value.second); + } + + private: + typedef Unordered_map<Const_section_id, Output_merge_base*, + Const_section_id_hash> + Merge_sections_by_id; + + typedef Unordered_map<Merge_section_properties, Output_merge_base*, + Merge_section_properties::hash, + Merge_section_properties::equal_to> + Merge_sections_by_properties; + + typedef Unordered_map<Const_section_id, Output_relaxed_input_section*, + Const_section_id_hash> + Relaxed_input_sections_by_id; + + // Whether this is valid + bool is_valid_; + // Merge sections by merge section properties. + Merge_sections_by_properties merge_sections_by_properties_; + // Merge sections by section IDs. + Merge_sections_by_id merge_sections_by_id_; + // Relaxed sections by section IDs. + Relaxed_input_sections_by_id relaxed_input_sections_by_id_; +}; + // An output section. We don't expect to have too many output // sections, so we don't bother to do a template on the size. @@ -2766,263 +2948,6 @@ class Output_section : public Output_data // The next few calls are for linker script support. - // We need to export the input sections to linker scripts. Previously - // we export a pair of Relobj pointer and section index. We now need to - // handle relaxed input sections as well. So we use this class. - class Simple_input_section - { - private: - static const unsigned int invalid_shndx = static_cast<unsigned int>(-1); - - public: - Simple_input_section(Relobj *relobj, unsigned int shndx) - : shndx_(shndx) - { - gold_assert(shndx != invalid_shndx); - this->u_.relobj = relobj; - } - - Simple_input_section(Output_relaxed_input_section* section) - : shndx_(invalid_shndx) - { this->u_.relaxed_input_section = section; } - - // Whether this is a relaxed section. - bool - is_relaxed_input_section() const - { return this->shndx_ == invalid_shndx; } - - // Return object of an input section. - Relobj* - relobj() const - { - return ((this->shndx_ != invalid_shndx) - ? this->u_.relobj - : this->u_.relaxed_input_section->relobj()); - } - - // Return index of an input section. - unsigned int - shndx() const - { - return ((this->shndx_ != invalid_shndx) - ? this->shndx_ - : this->u_.relaxed_input_section->shndx()); - } - - // Return the Output_relaxed_input_section object of a relaxed section. - Output_relaxed_input_section* - relaxed_input_section() const - { - gold_assert(this->shndx_ == invalid_shndx); - return this->u_.relaxed_input_section; - } - - private: - // Pointer to either an Relobj or an Output_relaxed_input_section. - union - { - Relobj* relobj; - Output_relaxed_input_section* relaxed_input_section; - } u_; - // Section index for an non-relaxed section or invalid_shndx for - // a relaxed section. - unsigned int shndx_; - }; - - // Store the list of input sections for this Output_section into the - // list passed in. This removes the input sections, leaving only - // any Output_section_data elements. This returns the size of those - // Output_section_data elements. ADDRESS is the address of this - // output section. FILL is the fill value to use, in case there are - // any spaces between the remaining Output_section_data elements. - uint64_t - get_input_sections(uint64_t address, const std::string& fill, - std::list<Simple_input_section>*); - - // Add a simple input section. - void - add_simple_input_section(const Simple_input_section& input_section, - off_t data_size, uint64_t addralign); - - // Set the current size of the output section. - void - set_current_data_size(off_t size) - { this->set_current_data_size_for_child(size); } - - // Get the current size of the output section. - off_t - current_data_size() const - { return this->current_data_size_for_child(); } - - // End of linker script support. - - // Save states before doing section layout. - // This is used for relaxation. - void - save_states(); - - // Restore states prior to section layout. - void - restore_states(); - - // Discard states. - void - discard_states(); - - // Convert existing input sections to relaxed input sections. - void - convert_input_sections_to_relaxed_sections( - const std::vector<Output_relaxed_input_section*>& sections); - - // Find a relaxed input section to an input section in OBJECT - // with index SHNDX. Return NULL if none is found. - const Output_relaxed_input_section* - find_relaxed_input_section(const Relobj* object, unsigned int shndx) const; - - // Whether section offsets need adjustment due to relaxation. - bool - section_offsets_need_adjustment() const - { return this->section_offsets_need_adjustment_; } - - // Set section_offsets_need_adjustment to be true. - void - set_section_offsets_need_adjustment() - { this->section_offsets_need_adjustment_ = true; } - - // Adjust section offsets of input sections in this. This is - // requires if relaxation caused some input sections to change sizes. - void - adjust_section_offsets(); - - // Whether this is a NOLOAD section. - bool - is_noload() const - { return this->is_noload_; } - - // Set NOLOAD flag. - void - set_is_noload() - { this->is_noload_ = true; } - - // Print merge statistics to stderr. - void - print_merge_stats(); - - protected: - // Return the output section--i.e., the object itself. - Output_section* - do_output_section() - { return this; } - - const Output_section* - do_output_section() const - { return this; } - - // Return the section index in the output file. - unsigned int - do_out_shndx() const - { - gold_assert(this->out_shndx_ != -1U); - return this->out_shndx_; - } - - // Set the output section index. - void - do_set_out_shndx(unsigned int shndx) - { - gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx); - this->out_shndx_ = shndx; - } - - // Set the final data size of the Output_section. For a typical - // Output_section, there is nothing to do, but if there are any - // Output_section_data objects we need to set their final addresses - // here. - virtual void - set_final_data_size(); - - // Reset the address and file offset. - void - do_reset_address_and_file_offset(); - - // Return true if address and file offset already have reset values. In - // other words, calling reset_address_and_file_offset will not change them. - bool - do_address_and_file_offset_have_reset_values() const; - - // Write the data to the file. For a typical Output_section, this - // does nothing: the data is written out by calling Object::Relocate - // on each input object. But if there are any Output_section_data - // objects we do need to write them out here. - virtual void - do_write(Output_file*); - - // Return the address alignment--function required by parent class. - uint64_t - do_addralign() const - { return this->addralign_; } - - // Return whether there is a load address. - bool - do_has_load_address() const - { return this->has_load_address_; } - - // Return the load address. - uint64_t - do_load_address() const - { - gold_assert(this->has_load_address_); - return this->load_address_; - } - - // Return whether this is an Output_section. - bool - do_is_section() const - { return true; } - - // Return whether this is a section of the specified type. - bool - do_is_section_type(elfcpp::Elf_Word type) const - { return this->type_ == type; } - - // Return whether the specified section flag is set. - bool - do_is_section_flag_set(elfcpp::Elf_Xword flag) const - { return (this->flags_ & flag) != 0; } - - // Set the TLS offset. Called only for SHT_TLS sections. - void - do_set_tls_offset(uint64_t tls_base); - - // Return the TLS offset, relative to the base of the TLS segment. - // Valid only for SHT_TLS sections. - uint64_t - do_tls_offset() const - { return this->tls_offset_; } - - // This may be implemented by a child class. - virtual void - do_finalize_name(Layout*) - { } - - // Print to the map file. - virtual void - do_print_to_mapfile(Mapfile*) const; - - // Record that this section requires postprocessing after all - // relocations have been applied. This is called by a child class. - void - set_requires_postprocessing() - { - this->requires_postprocessing_ = true; - this->after_input_sections_ = true; - } - - // Write all the data of an Output_section into the postprocessing - // buffer. - void - write_to_postprocessing_buffer(); - // In some cases we need to keep a list of the input sections // associated with this output section. We only need the list if we // might have to change the offsets of the input section within the @@ -3088,13 +3013,29 @@ class Output_section : public Output_data uint64_t addralign() const { - if (!this->is_input_section()) + if (this->p2align_ != 0) + return static_cast<uint64_t>(1) << (this->p2align_ - 1); + else if (!this->is_input_section()) return this->u2_.posd->addralign(); - return (this->p2align_ == 0 - ? 0 - : static_cast<uint64_t>(1) << (this->p2align_ - 1)); + else + return 0; } + // Set the required alignment, which must be either 0 or a power of 2. + // For input sections that are sub-classes of Output_section_data, a + // alignment of zero means asking the underlying object for alignment. + void + set_addralign(uint64_t addralign) + { + if (addralign == 0) + this->p2align_ = 0; + else + { + gold_assert((addralign & (addralign - 1)) == 0); + this->p2align_ = ffsll(static_cast<long long>(addralign)); + } + } + // Return the required size. off_t data_size() const; @@ -3122,6 +3063,14 @@ class Output_section : public Output_data && this->addralign() == addralign); } + // Return whether this is a merge section for some input section. + bool + is_merge_section() const + { + return (this->shndx_ == MERGE_DATA_SECTION_CODE + || this->shndx_ == MERGE_STRING_SECTION_CODE); + } + // Return whether this is a relaxed input section. bool is_relaxed_input_section() const @@ -3136,27 +3085,11 @@ class Output_section : public Output_data // Return the object for an input section. Relobj* - relobj() const - { - if (this->is_input_section()) - return this->u2_.object; - else if (this->is_relaxed_input_section()) - return this->u2_.poris->relobj(); - else - gold_unreachable(); - } + relobj() const; // Return the input section index for an input section. unsigned int - shndx() const - { - if (this->is_input_section()) - return this->shndx_; - else if (this->is_relaxed_input_section()) - return this->u2_.poris->shndx(); - else - gold_unreachable(); - } + shndx() const; // For non-input-sections, return the associated Output_section_data // object. @@ -3167,6 +3100,14 @@ class Output_section : public Output_data return this->u2_.posd; } + // For a merge section, return the Output_merge_base pointer. + Output_merge_base* + output_merge_base() const + { + gold_assert(this->is_merge_section()); + return this->u2_.pomb; + } + // Return the Output_relaxed_input_section object. Output_relaxed_input_section* relaxed_input_section() const @@ -3289,11 +3230,206 @@ class Output_section : public Output_data // For OUTPUT_SECTION_CODE or MERGE_DATA_SECTION_CODE or // MERGE_STRING_SECTION_CODE, the data. Output_section_data* posd; + Output_merge_base* pomb; // For RELAXED_INPUT_SECTION_CODE, the data. Output_relaxed_input_section* poris; } u2_; }; + // Store the list of input sections for this Output_section into the + // list passed in. This removes the input sections, leaving only + // any Output_section_data elements. This returns the size of those + // Output_section_data elements. ADDRESS is the address of this + // output section. FILL is the fill value to use, in case there are + // any spaces between the remaining Output_section_data elements. + uint64_t + get_input_sections(uint64_t address, const std::string& fill, + std::list<Input_section>*); + + // Add a script input section. A script input section can either be + // a plain input section or a sub-class of Output_section_data. + void + add_script_input_section(const Input_section& input_section); + + // Set the current size of the output section. + void + set_current_data_size(off_t size) + { this->set_current_data_size_for_child(size); } + + // Get the current size of the output section. + off_t + current_data_size() const + { return this->current_data_size_for_child(); } + + // End of linker script support. + + // Save states before doing section layout. + // This is used for relaxation. + void + save_states(); + + // Restore states prior to section layout. + void + restore_states(); + + // Discard states. + void + discard_states(); + + // Convert existing input sections to relaxed input sections. + void + convert_input_sections_to_relaxed_sections( + const std::vector<Output_relaxed_input_section*>& sections); + + // Find a relaxed input section to an input section in OBJECT + // with index SHNDX. Return NULL if none is found. + const Output_relaxed_input_section* + find_relaxed_input_section(const Relobj* object, unsigned int shndx) const; + + // Whether section offsets need adjustment due to relaxation. + bool + section_offsets_need_adjustment() const + { return this->section_offsets_need_adjustment_; } + + // Set section_offsets_need_adjustment to be true. + void + set_section_offsets_need_adjustment() + { this->section_offsets_need_adjustment_ = true; } + + // Adjust section offsets of input sections in this. This is + // requires if relaxation caused some input sections to change sizes. + void + adjust_section_offsets(); + + // Whether this is a NOLOAD section. + bool + is_noload() const + { return this->is_noload_; } + + // Set NOLOAD flag. + void + set_is_noload() + { this->is_noload_ = true; } + + // Print merge statistics to stderr. + void + print_merge_stats(); + + protected: + // Return the output section--i.e., the object itself. + Output_section* + do_output_section() + { return this; } + + const Output_section* + do_output_section() const + { return this; } + + // Return the section index in the output file. + unsigned int + do_out_shndx() const + { + gold_assert(this->out_shndx_ != -1U); + return this->out_shndx_; + } + + // Set the output section index. + void + do_set_out_shndx(unsigned int shndx) + { + gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx); + this->out_shndx_ = shndx; + } + + // Set the final data size of the Output_section. For a typical + // Output_section, there is nothing to do, but if there are any + // Output_section_data objects we need to set their final addresses + // here. + virtual void + set_final_data_size(); + + // Reset the address and file offset. + void + do_reset_address_and_file_offset(); + + // Return true if address and file offset already have reset values. In + // other words, calling reset_address_and_file_offset will not change them. + bool + do_address_and_file_offset_have_reset_values() const; + + // Write the data to the file. For a typical Output_section, this + // does nothing: the data is written out by calling Object::Relocate + // on each input object. But if there are any Output_section_data + // objects we do need to write them out here. + virtual void + do_write(Output_file*); + + // Return the address alignment--function required by parent class. + uint64_t + do_addralign() const + { return this->addralign_; } + + // Return whether there is a load address. + bool + do_has_load_address() const + { return this->has_load_address_; } + + // Return the load address. + uint64_t + do_load_address() const + { + gold_assert(this->has_load_address_); + return this->load_address_; + } + + // Return whether this is an Output_section. + bool + do_is_section() const + { return true; } + + // Return whether this is a section of the specified type. + bool + do_is_section_type(elfcpp::Elf_Word type) const + { return this->type_ == type; } + + // Return whether the specified section flag is set. + bool + do_is_section_flag_set(elfcpp::Elf_Xword flag) const + { return (this->flags_ & flag) != 0; } + + // Set the TLS offset. Called only for SHT_TLS sections. + void + do_set_tls_offset(uint64_t tls_base); + + // Return the TLS offset, relative to the base of the TLS segment. + // Valid only for SHT_TLS sections. + uint64_t + do_tls_offset() const + { return this->tls_offset_; } + + // This may be implemented by a child class. + virtual void + do_finalize_name(Layout*) + { } + + // Print to the map file. + virtual void + do_print_to_mapfile(Mapfile*) const; + + // Record that this section requires postprocessing after all + // relocations have been applied. This is called by a child class. + void + set_requires_postprocessing() + { + this->requires_postprocessing_ = true; + this->after_input_sections_ = true; + } + + // Write all the data of an Output_section into the postprocessing + // buffer. + void + write_to_postprocessing_buffer(); + typedef std::vector<Input_section> Input_section_list; // Allow a child class to access the input sections. @@ -3436,78 +3572,6 @@ class Output_section : public Output_data typedef std::vector<Fill> Fill_list; - // This class describes properties of merge data sections. It is used - // as a key type for maps. - class Merge_section_properties - { - public: - Merge_section_properties(bool is_string, uint64_t entsize, - uint64_t addralign) - : is_string_(is_string), entsize_(entsize), addralign_(addralign) - { } - - // Whether this equals to another Merge_section_properties MSP. - bool - eq(const Merge_section_properties& msp) const - { - return ((this->is_string_ == msp.is_string_) - && (this->entsize_ == msp.entsize_) - && (this->addralign_ == msp.addralign_)); - } - - // Compute a hash value for this using 64-bit FNV-1a hash. - size_t - hash_value() const - { - uint64_t h = 14695981039346656037ULL; // FNV offset basis. - uint64_t prime = 1099511628211ULL; - h = (h ^ static_cast<uint64_t>(this->is_string_)) * prime; - h = (h ^ static_cast<uint64_t>(this->entsize_)) * prime; - h = (h ^ static_cast<uint64_t>(this->addralign_)) * prime; - return h; - } - - // Functors for associative containers. - struct equal_to - { - bool - operator()(const Merge_section_properties& msp1, - const Merge_section_properties& msp2) const - { return msp1.eq(msp2); } - }; - - struct hash - { - size_t - operator()(const Merge_section_properties& msp) const - { return msp.hash_value(); } - }; - - private: - // Whether this merge data section is for strings. - bool is_string_; - // Entsize of this merge data section. - uint64_t entsize_; - // Address alignment. - uint64_t addralign_; - }; - - // Map that link Merge_section_properties to Output_merge_base. - typedef Unordered_map<Merge_section_properties, Output_merge_base*, - Merge_section_properties::hash, - Merge_section_properties::equal_to> - Merge_section_by_properties_map; - - // Map that link Const_section_id to Output_section_data. - typedef Unordered_map<Const_section_id, Output_section_data*, - Const_section_id_hash> - Output_section_data_by_input_section_map; - - // Map that link Const_section_id to Output_relaxed_input_section. - typedef Unordered_map<Const_section_id, Output_relaxed_input_section*, - Const_section_id_hash> - Output_relaxed_input_section_by_input_section_map; - // Map used during relaxation of existing sections. This map // a section id an input section list index. We assume that // Input_section_list is a vector. @@ -3518,10 +3582,12 @@ class Output_section : public Output_data add_output_section_data(Input_section*); // Add an SHF_MERGE input section. Returns true if the section was - // handled. + // handled. If KEEPS_INPUT_SECTIONS is true, the output merge section + // stores information about the merged input sections. bool add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags, - uint64_t entsize, uint64_t addralign); + uint64_t entsize, uint64_t addralign, + bool keeps_input_sections); // Add an output SHF_MERGE section POSD to this output section. // IS_STRING indicates whether it is a SHF_STRINGS section, and @@ -3554,6 +3620,10 @@ class Output_section : public Output_data const Relaxation_map& map, Input_section_list* input_sections); + // Build the lookup maps for merge and relaxed input sections. + void + build_lookup_maps() const; + // Most of these fields are only valid after layout. // The name of the section. This will point into a Stringpool. @@ -3676,17 +3746,8 @@ class Output_section : public Output_data uint64_t tls_offset_; // Saved checkpoint. Checkpoint_output_section* checkpoint_; - // Map from input sections to merge sections. - Output_section_data_by_input_section_map merge_section_map_; - // Map from merge section properties to merge_sections; - Merge_section_by_properties_map merge_section_by_properties_map_; - // Map from input sections to relaxed input sections. This is mutable - // because it is updated lazily. We may need to update it in a - // const qualified method. - mutable Output_relaxed_input_section_by_input_section_map - relaxed_input_section_map_; - // Whether relaxed_input_section_map_ is valid. - mutable bool is_relaxed_input_section_map_valid_; + // Fast lookup maps for merged and relaxed input sections. + Output_section_lookup_maps* lookup_maps_; }; // An output segment. PT_LOAD segments are built from collections of diff --git a/binutils-2.19/gold/script-sections.cc b/binutils-2.19/gold/script-sections.cc index 99f0dbf..5cfb07c 100644 --- a/binutils-2.19/gold/script-sections.cc +++ b/binutils-2.19/gold/script-sections.cc @@ -525,7 +525,7 @@ class Output_section_element { public: // A list of input sections. - typedef std::list<Output_section::Simple_input_section> Input_section_list; + typedef std::list<Output_section::Input_section> Input_section_list; Output_section_element() { } @@ -1172,13 +1172,13 @@ Output_section_element_input::match_name(const char* file_name, class Input_section_info { public: - Input_section_info(const Output_section::Simple_input_section& input_section) + Input_section_info(const Output_section::Input_section& input_section) : input_section_(input_section), section_name_(), size_(0), addralign_(1) { } // Return the simple input section. - const Output_section::Simple_input_section& + const Output_section::Input_section& input_section() const { return this->input_section_; } @@ -1224,7 +1224,7 @@ class Input_section_info private: // Input section, can be a relaxed section. - Output_section::Simple_input_section input_section_; + Output_section::Input_section input_section_; // Name of the section. std::string section_name_; // Section size. @@ -1394,9 +1394,20 @@ Output_section_element_input::set_section_addresses( p != matching_sections[i].end(); ++p) { - uint64_t this_subalign = p->addralign(); + // Override the original address alignment if SUBALIGN is specified + // and is greater than the original alignment. We need to make a + // copy of the input section to modify the alignment. + Output_section::Input_section sis(p->input_section()); + + uint64_t this_subalign = sis.addralign(); + if (!sis.is_input_section()) + sis.output_section_data()->finalize_data_size(); + uint64_t data_size = sis.data_size(); if (this_subalign < subalign) - this_subalign = subalign; + { + this_subalign = subalign; + sis.set_addralign(subalign); + } uint64_t address = align_address(dot, this_subalign); @@ -1410,11 +1421,8 @@ Output_section_element_input::set_section_addresses( layout->new_output_section_data_from_script(posd); } - output_section->add_simple_input_section(p->input_section(), - p->size(), - this_subalign); - - dot = address + p->size(); + output_section->add_script_input_section(sis); + dot = address + data_size; } } @@ -2351,7 +2359,7 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*, uint64_t* dot_value, uint64_t* load_address) { - typedef std::list<Output_section::Simple_input_section> Input_section_list; + typedef std::list<Output_section::Input_section> Input_section_list; bool have_load_address = *load_address != *dot_value; @@ -2373,25 +2381,12 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*, p != input_sections.end(); ++p) { - uint64_t addralign; - uint64_t size; - - // We know what are single-threaded, so it is OK to lock the - // object. - { - const Task* task = reinterpret_cast<const Task*>(-1); - Task_lock_obj<Object> tl(task, p->relobj()); - addralign = p->relobj()->section_addralign(p->shndx()); - if (p->is_relaxed_input_section()) - // We use current data size because relxed section sizes may not - // have finalized yet. - size = p->relaxed_input_section()->current_data_size(); - else - size = p->relobj()->section_size(p->shndx()); - } - + uint64_t addralign = p->addralign(); + if (!p->is_input_section()) + p->output_section_data()->finalize_data_size(); + uint64_t size = p->data_size(); address = align_address(address, addralign); - this->os_->add_simple_input_section(*p, size, addralign); + this->os_->add_script_input_section(*p); address += size; } diff --git a/binutils-2.19/gold/target-reloc.h b/binutils-2.19/gold/target-reloc.h index 510eea0..0bd060b 100644 --- a/binutils-2.19/gold/target-reloc.h +++ b/binutils-2.19/gold/target-reloc.h @@ -515,7 +515,7 @@ relocate_for_relocatable( const Relocatable_relocs* rr, unsigned char* view, typename elfcpp::Elf_types<size>::Elf_Addr view_address, - section_size_type, + section_size_type view_size, unsigned char* reloc_view, section_size_type reloc_view_size) { @@ -537,6 +537,19 @@ relocate_for_relocatable( if (strategy == Relocatable_relocs::RELOC_DISCARD) continue; + if (strategy == Relocatable_relocs::RELOC_SPECIAL) + { + // Target wants to handle this relocation. + Sized_target<size, big_endian>* target = + parameters->sized_target<size, big_endian>(); + target->relocate_special_relocatable(relinfo, sh_type, prelocs, + i, output_section, + offset_in_output_section, + view, view_address, + view_size, pwrite); + pwrite += reloc_size; + continue; + } Reltype reloc(prelocs); Reltype_write reloc_write(pwrite); diff --git a/binutils-2.19/gold/target.h b/binutils-2.19/gold/target.h index 7429b63..02cbee2 100644 --- a/binutils-2.19/gold/target.h +++ b/binutils-2.19/gold/target.h @@ -673,7 +673,37 @@ class Sized_target : public Target section_size_type view_size, unsigned char* reloc_view, section_size_type reloc_view_size) = 0; + + // Perform target-specific processing in a relocatable link. This is + // only used if we use the relocation strategy RELOC_SPECIAL. + // RELINFO points to a Relocation_info structure. SH_TYPE is the relocation + // section type. PRELOC_IN points to the original relocation. RELNUM is + // the index number of the relocation in the relocation section. + // OUTPUT_SECTION is the output section to which the relocation is applied. + // OFFSET_IN_OUTPUT_SECTION is the offset of the relocation input section + // within the output section. VIEW points to the output view of the + // output section. VIEW_ADDRESS is output address of the view. VIEW_SIZE + // is the size of the output view and PRELOC_OUT points to the new + // relocation in the output object. + // + // A target only needs to override this if the generic code in + // target-reloc.h cannot handle some relocation types. + virtual void + relocate_special_relocatable(const Relocate_info<size, big_endian>* + /*relinfo */, + unsigned int /* sh_type */, + const unsigned char* /* preloc_in */, + size_t /* relnum */, + Output_section* /* output_section */, + off_t /* offset_in_output_section */, + unsigned char* /* view */, + typename elfcpp::Elf_types<size>::Elf_Addr + /* view_address */, + section_size_type /* view_size */, + unsigned char* /* preloc_out*/) + { gold_unreachable(); } + protected: Sized_target(const Target::Target_info* pti) : Target(pti) diff --git a/binutils-2.19/ld/Makefile.am b/binutils-2.19/ld/Makefile.am index 0093c88..3ba9d8c 100644 --- a/binutils-2.19/ld/Makefile.am +++ b/binutils-2.19/ld/Makefile.am @@ -90,7 +90,8 @@ CXX_FOR_TARGET = ` \ fi; \ fi` -noinst_PROGRAMS = ld-new +transform = s/^ld-new$$/$(installed_linker)/;@program_transform_name@ +bin_PROGRAMS = ld-new info_TEXINFOS = ld.texinfo ld_TEXINFOS = configdoc.texi noinst_TEXINFOS = ldint.texinfo @@ -1887,21 +1888,25 @@ install-html-recursive: .PHONY: install-exec-local install-data-local -install-exec-local: ld-new$(EXEEXT) - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(tooldir)/bin - @list='$(noinst_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - n=`echo ld | sed '$(transform)'`; \ - if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \ - rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ - ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ - || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ - fi - +install-exec-local: ld-new$(EXEEXT) install-binPROGRAMS + $(mkinstalldirs) $(DESTDIR)$(tooldir)/bin + n=`echo $(installed_linker) | sed '$(transform)'`; \ + if test "$(bindir)" != "$(tooldir)/bin"; then \ + rm -f $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + fi; \ + if test "x$(install_as_default)" = "xyes"; then \ + ld=`echo ld | sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/$$ld$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(bindir)/$$ld$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(bindir)/$$ld$(EXEEXT); \ + if test "$(bindir)" != "$(tooldir)/bin"; then \ + rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + fi; \ + fi install-data-local: $(mkinstalldirs) $(DESTDIR)$(scriptdir)/ldscripts for f in ldscripts/*; do \ diff --git a/binutils-2.19/ld/Makefile.in b/binutils-2.19/ld/Makefile.in index 309e8e6..720c82b 100644 --- a/binutils-2.19/ld/Makefile.in +++ b/binutils-2.19/ld/Makefile.in @@ -27,7 +27,6 @@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : @@ -37,7 +36,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -noinst_PROGRAMS = ld-new$(EXEEXT) +bin_PROGRAMS = ld-new$(EXEEXT) # Automake 1.9 will only build info files in the objdir if they are # mentioned in DISTCLEANFILES. It doesn't have to be unconditional, @@ -74,7 +73,9 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = po/Makefile.in -PROGRAMS = $(noinst_PROGRAMS) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) am_ld_new_OBJECTS = ldgram.$(OBJEXT) ldlex.$(OBJEXT) lexsup.$(OBJEXT) \ ldlang.$(OBJEXT) mri.$(OBJEXT) ldctor.$(OBJEXT) \ ldmain.$(OBJEXT) ldwrite.$(OBJEXT) ldexp.$(OBJEXT) \ @@ -121,7 +122,6 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive man1dir = $(mandir)/man1 -am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) ETAGS = etags @@ -129,6 +129,7 @@ CTAGS = ctags DEJATOOL = $(PACKAGE) RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir DIST_SUBDIRS = $(SUBDIRS) +transform = s/^ld-new$$/$(installed_linker)/;@program_transform_name@ ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ @@ -262,7 +263,9 @@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ +install_as_default = @install_as_default@ install_sh = @install_sh@ +installed_linker = @installed_linker@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ @@ -789,9 +792,30 @@ distclean-hdr: -rm -f config.h stamp-h1 po/Makefile.in: $(top_builddir)/config.status $(top_srcdir)/po/Make-in cd $(top_builddir) && $(SHELL) ./config.status $@ +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; for p in $$list; do \ +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ @@ -1144,7 +1168,7 @@ check: check-recursive all-am: Makefile $(PROGRAMS) $(MANS) config.h installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(man1dir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-recursive @@ -1182,8 +1206,7 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive -clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ - mostlyclean-am +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1206,7 +1229,7 @@ info-am: $(INFO_DEPS) install-data-am: install-data-local install-man -install-exec-am: install-exec-local +install-exec-am: install-binPROGRAMS install-exec-local install-info: install-info-recursive @@ -1264,29 +1287,30 @@ ps: ps-recursive ps-am: $(PSS) -uninstall-am: uninstall-man +uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-info: uninstall-info-recursive uninstall-man: uninstall-man1 .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ - check-DEJAGNU check-am clean clean-generic clean-info \ - clean-libtool clean-noinstPROGRAMS clean-recursive ctags \ - ctags-recursive dist-info distclean distclean-DEJAGNU \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-local distclean-recursive \ - distclean-tags dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-data-local \ - install-exec install-exec-am install-exec-local install-info \ - install-info-am install-man install-man1 install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-aminfo \ - maintainer-clean-generic maintainer-clean-recursive \ - mostlyclean mostlyclean-aminfo mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool mostlyclean-local \ - mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am uninstall-info-am uninstall-man \ + check-DEJAGNU check-am clean clean-binPROGRAMS clean-generic \ + clean-info clean-libtool clean-recursive ctags ctags-recursive \ + dist-info distclean distclean-DEJAGNU distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-local distclean-recursive distclean-tags dvi dvi-am \ + html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-data-local install-exec install-exec-am \ + install-exec-local install-info install-info-am install-man \ + install-man1 install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-aminfo \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + mostlyclean-local mostlyclean-recursive pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-info-am uninstall-man \ uninstall-man1 @@ -2693,21 +2717,25 @@ install-html-recursive: .PHONY: install-exec-local install-data-local -install-exec-local: ld-new$(EXEEXT) - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(tooldir)/bin - @list='$(noinst_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - n=`echo ld | sed '$(transform)'`; \ - if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \ - rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ - ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ - || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ - fi - +install-exec-local: ld-new$(EXEEXT) install-binPROGRAMS + $(mkinstalldirs) $(DESTDIR)$(tooldir)/bin + n=`echo $(installed_linker) | sed '$(transform)'`; \ + if test "$(bindir)" != "$(tooldir)/bin"; then \ + rm -f $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/$(installed_linker)$(EXEEXT); \ + fi; \ + if test "x$(install_as_default)" = "xyes"; then \ + ld=`echo ld | sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/$$ld$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(bindir)/$$ld$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(bindir)/$$ld$(EXEEXT); \ + if test "$(bindir)" != "$(tooldir)/bin"; then \ + rm -f $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + ln $(DESTDIR)$(bindir)/$$n$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ + || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(DESTDIR)$(tooldir)/bin/ld$(EXEEXT); \ + fi; \ + fi install-data-local: $(mkinstalldirs) $(DESTDIR)$(scriptdir)/ldscripts for f in ldscripts/*; do \ diff --git a/binutils-2.19/ld/configure b/binutils-2.19/ld/configure index c0ad08b..eb7cb9c 100755 --- a/binutils-2.19/ld/configure +++ b/binutils-2.19/ld/configure @@ -458,7 +458,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE use_sysroot TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE WARN_CFLAGS NO_WERROR CPP EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE YACC LEX LEXLIB LEX_OUTPUT_ROOT MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GENINSRC_NEVER_TRUE GENINSRC_NEVER_FALSE HDEFINES HOSTING_CRT0 HOSTING_LIBS NATIVE_LIB_DIRS STRINGIFY EMUL EMULATION_OFILES EMUL_EXTRA_OFILES LIB_PATH EMULATION_LIBPATH TESTBFDLIB datarootdir docdir htmldir LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE use_sysroot TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE install_as_default installed_linker WARN_CFLAGS NO_WERROR CPP EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE YACC LEX LEXLIB LEX_OUTPUT_ROOT MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GENINSRC_NEVER_TRUE GENINSRC_NEVER_FALSE HDEFINES HOSTING_CRT0 HOSTING_LIBS NATIVE_LIB_DIRS STRINGIFY EMUL EMULATION_OFILES EMUL_EXTRA_OFILES LIB_PATH EMULATION_LIBPATH TESTBFDLIB datarootdir docdir htmldir LIBOBJS LTLIBOBJS' ac_subst_files='TDIRS' ac_pwd=`pwd` @@ -1004,6 +1004,7 @@ Optional Features: --enable-dependency-tracking do not reject slow dependency extractors --enable-targets alternative target configurations --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) + --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]] --enable-got=<type> GOT handling scheme (target, single, negative, multigot) --enable-werror treat compile warnings as errors @@ -3340,6 +3341,31 @@ fi; +# Check whether --enable-gold or --disable-gold was given. +if test "${enable_gold+set}" = set; then + enableval="$enable_gold" + case "${enableval}" in + yes|both/gold) + install_as_default=no + installed_linker=ld.bfd + ;; + both|both/ld) + install_as_default=yes + installed_linker=ld.bfd + ;; + *) + { { echo "$as_me:$LINENO: error: invalid --enable-gold argument" >&5 +echo "$as_me: error: invalid --enable-gold argument" >&2;} + { (exit 1); exit 1; }; } + ;; + esac +else + install_as_default=ld + installed_linker=ld +fi; + + + # Check whether --enable-got or --disable-got was given. if test "${enable_got+set}" = set; then enableval="$enable_got" @@ -5542,13 +5568,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:5545: $ac_compile\"" >&5) + (eval echo "\"\$as_me:5571: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:5548: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:5574: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:5551: output\"" >&5) + (eval echo "\"\$as_me:5577: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6603,7 +6629,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6606 "configure"' > conftest.$ac_ext + echo '#line 6632 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7230,11 +7256,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7233: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7259: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7237: \$? = $ac_status" >&5 + echo "$as_me:7263: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7552,11 +7578,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7555: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7581: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7559: \$? = $ac_status" >&5 + echo "$as_me:7585: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7657,11 +7683,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7660: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7686: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7664: \$? = $ac_status" >&5 + echo "$as_me:7690: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7712,11 +7738,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7715: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7741: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7719: \$? = $ac_status" >&5 + echo "$as_me:7745: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10509,7 +10535,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10512 "configure" +#line 10538 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10609,7 +10635,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10612 "configure" +#line 10638 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14456,6 +14482,8 @@ s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@use_sysroot@,$use_sysroot,;t t s,@TARGET_SYSTEM_ROOT@,$TARGET_SYSTEM_ROOT,;t t s,@TARGET_SYSTEM_ROOT_DEFINE@,$TARGET_SYSTEM_ROOT_DEFINE,;t t +s,@install_as_default@,$install_as_default,;t t +s,@installed_linker@,$installed_linker,;t t s,@WARN_CFLAGS@,$WARN_CFLAGS,;t t s,@NO_WERROR@,$NO_WERROR,;t t s,@CPP@,$CPP,;t t diff --git a/binutils-2.19/ld/configure.in b/binutils-2.19/ld/configure.in index 8ec534f..ba5be57 100644 --- a/binutils-2.19/ld/configure.in +++ b/binutils-2.19/ld/configure.in @@ -68,6 +68,29 @@ AC_SUBST(use_sysroot) AC_SUBST(TARGET_SYSTEM_ROOT) AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) +dnl Use --enable-gold to decide if this linker should be the default. +dnl "install_as_default" is set to false if gold is the default linker. +dnl "installed_linker" is the installed BFD linker name. +AC_ARG_ENABLE(gold, +[[ --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]]]], +[case "${enableval}" in + yes|both/gold) + install_as_default=no + installed_linker=ld.bfd + ;; + both|both/ld) + install_as_default=yes + installed_linker=ld.bfd + ;; + *) + AC_MSG_ERROR([invalid --enable-gold argument]) + ;; + esac], +[install_as_default=ld + installed_linker=ld]) +AC_SUBST(install_as_default) +AC_SUBST(installed_linker) + AC_ARG_ENABLE([got], AS_HELP_STRING([--enable-got=<type>], [GOT handling scheme (target, single, negative, multigot)]), |