[tor-commits] [tor-browser-build/master] Bug 16472: update binutils to 2.26.1

gk at torproject.org gk at torproject.org
Tue May 29 20:19:10 UTC 2018


commit b24500f6880e2c461050e248c0f7e587b5201d51
Author: Nicolas Vigier <boklm at torproject.org>
Date:   Wed Feb 14 13:31:29 2018 +0100

    Bug 16472: update binutils to 2.26.1
---
 keyring/binutils.gpg                               |  Bin 25772 -> 1169 bytes
 projects/binutils/64bit-fixups.patch               |   31 +-
 projects/binutils/binutils-224-gold.patch          |   98 --
 projects/binutils/build                            |   10 +-
 projects/binutils/config                           |   11 +-
 projects/binutils/enable-reloc-section-ld.patch    |   83 +-
 projects/binutils/fix-warning-bfd.patch            |  186 ----
 .../binutils/fix-windows-reproducibility.patch     | 1034 ++++++++++++++++++++
 projects/binutils/peXXigen.patch                   |   43 +-
 projects/mingw-w64/build                           |    2 +-
 projects/nsis/build                                |    9 +-
 projects/nsis/config                               |    1 +
 projects/nsis/no-insert-timestamp.patch            |   27 +
 projects/openssl/config                            |    2 +-
 projects/selfrando/config                          |    2 +-
 projects/zlib/build                                |    4 +-
 rbm.conf                                           |    2 +-
 17 files changed, 1174 insertions(+), 371 deletions(-)

diff --git a/keyring/binutils.gpg b/keyring/binutils.gpg
index f24bb01..2de205d 100644
Binary files a/keyring/binutils.gpg and b/keyring/binutils.gpg differ
diff --git a/projects/binutils/64bit-fixups.patch b/projects/binutils/64bit-fixups.patch
index 33c0297..7dc1294 100644
--- a/projects/binutils/64bit-fixups.patch
+++ b/projects/binutils/64bit-fixups.patch
@@ -1,14 +1,19 @@
-From f3ba95e14437f10de8b8f296930ff2a8495d18c6 Mon Sep 17 00:00:00 2001
+From 05164a1162d5f6f696d7f7c4b1bc61ef06d1c288 Mon Sep 17 00:00:00 2001
 From: Georg Koppen <gk at torproject.org>
 Date: Tue, 12 Sep 2017 07:21:16 +0000
 Subject: [PATCH] 64bit fixups
 
+---
+ ld/emultempl/pep.em | 4 ++--
+ ld/pep-dll.c        | 1 +
+ ld/pep-dll.h        | 1 +
+ 3 files changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
-index b566903b14..27006bdf79 100644
+index fccbd63..f7c0a57 100644
 --- a/ld/emultempl/pep.em
 +++ b/ld/emultempl/pep.em
-@@ -730,7 +730,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
+@@ -742,7 +742,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
        pep_dll_exclude_all_symbols = 1;
        break;
      case OPTION_ENABLE_RELOC_SECTION:
@@ -17,17 +22,17 @@ index b566903b14..27006bdf79 100644
        break;
      case OPTION_EXCLUDE_LIBS:
        pep_dll_add_excludes (optarg, EXCLUDELIBS);
-@@ -1623,7 +1623,7 @@ gld_${EMULATION_NAME}_finish (void)
- 
+@@ -1862,7 +1862,7 @@ gld_${EMULATION_NAME}_finish (void)
  #ifdef DLL_SUPPORT
-   if (link_info.shared
--      || (!link_info.relocatable && pe_dll_enable_reloc_section)
-+      || (!link_info.relocatable && pep_dll_enable_reloc_section)
-       || (!link_info.relocatable && pep_def_file->num_exports != 0))
+   if (bfd_link_pic (&link_info)
+       || (!bfd_link_relocatable (&link_info)
+-          && pe_dll_enable_reloc_section)
++          && pep_dll_enable_reloc_section)
+       || (!bfd_link_relocatable (&link_info)
+           && pep_def_file->num_exports != 0))
      {
-       pep_dll_fill_sections (link_info.output_bfd, &link_info);
 diff --git a/ld/pep-dll.c b/ld/pep-dll.c
-index 0e5e8b1523..b5f99b90e0 100644
+index b8c017f..5ad5733 100644
 --- a/ld/pep-dll.c
 +++ b/ld/pep-dll.c
 @@ -31,6 +31,7 @@
@@ -39,7 +44,7 @@ index 0e5e8b1523..b5f99b90e0 100644
  #define pe_dll_stdcall_aliases      pep_dll_stdcall_aliases
  #define pe_dll_warn_dup_exports     pep_dll_warn_dup_exports
 diff --git a/ld/pep-dll.h b/ld/pep-dll.h
-index 1e7e3d65d4..c31e69cc8e 100644
+index 0a27c1f..95d9c15 100644
 --- a/ld/pep-dll.h
 +++ b/ld/pep-dll.h
 @@ -31,6 +31,7 @@ extern def_file * pep_def_file;
@@ -51,5 +56,5 @@ index 1e7e3d65d4..c31e69cc8e 100644
  extern int pep_dll_stdcall_aliases;
  extern int pep_dll_warn_dup_exports;
 -- 
-2.14.1
+2.1.4
 
diff --git a/projects/binutils/binutils-224-gold.patch b/projects/binutils/binutils-224-gold.patch
deleted file mode 100644
index a45e49c..0000000
--- a/projects/binutils/binutils-224-gold.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From f984741df04cd68bb116073fdfa9405808810ab4 Mon Sep 17 00:00:00 2001
-From: Cary Coutant <ccoutant at google.com>
-Date: Wed, 5 Feb 2014 22:59:02 -0800
-Subject: [PATCH] Fix issues with gold undefined symbol diagnostics.
-
-PR binutils/15435 complains that gold issues a visibility error for an
-weak undefined symbol with hidden visibility. The message should be
-suppressed if the symbol is a weak undef.
-
-An earlier patch to add an extra note about key functions when a class's
-vtable symbol is undefined missed a case where the reference to the
-vtable came from a shared library. This patch moves the check to a
-lower-level routine that catches both cases.
-
-gold/
-
-2014-02-05  Cary Coutant  <ccoutant at google.com>
-
-	* errors.cc (Errors::undefined_symbol): Move undef vtable symbol
-	check to here.
-	* target-reloc.h (is_strong_undefined): New function.
-	(relocate_section): Move undef vtable symbol check from here.
-	Check for is_strong_undefined.
-
-diff --git a/gold/ChangeLog b/gold/ChangeLog
-index dcf7ed41f8..dd7ef72980 100644
---- a/gold/ChangeLog
-+++ b/gold/ChangeLog
-@@ -1,3 +1,14 @@
-+2014-02-05  Cary Coutant  <ccoutant at google.com>
-+
-+	Fix issues with gold undefined symbol diagnostics.
-+
-+	PR binutils/15435
-+	* errors.cc (Errors::undefined_symbol): Move undef vtable symbol
-+	check to here.
-+	* target-reloc.h (is_strong_undefined): New function.
-+	(relocate_section): Move undef vtable symbol check from here.
-+	Check for is_strong_undefined.
-+
- 2013-11-22  Cary Coutant  <ccoutant at google.com>
- 
- 	* testsuite/Makefile.am (exception_x86_64_bnd_test): Use in-tree
-diff --git a/gold/errors.cc b/gold/errors.cc
-index b79764bd1d..98db0fdd86 100644
---- a/gold/errors.cc
-+++ b/gold/errors.cc
-@@ -193,6 +193,11 @@ Errors::undefined_symbol(const Symbol* sym, const std::string& location)
-     fprintf(stderr,
-             _("%s: %s: undefined reference to '%s', version '%s'\n"),
- 	    location.c_str(), zmsg, sym->demangled_name().c_str(), version);
-+
-+  if (sym->is_cxx_vtable())
-+    gold_info(_("%s: the vtable symbol may be undefined because "
-+		"the class is missing its key function"),
-+	      program_name);
- }
- 
- // Issue a debugging message.
-diff --git a/gold/target-reloc.h b/gold/target-reloc.h
-index b544c78f37..d609bcbaa8 100644
---- a/gold/target-reloc.h
-+++ b/gold/target-reloc.h
-@@ -144,6 +144,12 @@ class Default_comdat_behavior
-   }
- };
- 
-+inline bool
-+is_strong_undefined(const Symbol* sym)
-+{
-+  return sym->is_undefined() && sym->binding() != elfcpp::STB_WEAK;
-+}
-+
- // Give an error for a symbol with non-default visibility which is not
- // defined locally.
- 
-@@ -411,16 +417,10 @@ relocate_section(
- 	}
- 
-       if (issue_undefined_symbol_error(sym))
--	{
--	  gold_undefined_symbol_at_location(sym, relinfo, i, offset);
--	  if (sym->is_cxx_vtable())
--	    gold_info(_("%s: the vtable symbol may be undefined because "
--			"the class is missing its key function"),
--		      program_name);
--	}
-+	gold_undefined_symbol_at_location(sym, relinfo, i, offset);
-       else if (sym != NULL
- 	       && sym->visibility() != elfcpp::STV_DEFAULT
--	       && (sym->is_undefined() || sym->is_from_dynobj()))
-+	       && (is_strong_undefined(sym) || sym->is_from_dynobj()))
- 	visibility_error(sym);
- 
-       if (sym != NULL && sym->has_warning())
--- 
-2.11.0
-
diff --git a/projects/binutils/build b/projects/binutils/build
index ee6db1a..0d1c062 100644
--- a/projects/binutils/build
+++ b/projects/binutils/build
@@ -25,17 +25,13 @@ cd [% project %]-[% c("version") %]
   patch -p1 < ../peXXigen.patch
   # Needed for the hardening...
   patch -p1 < ../enable-reloc-section-ld.patch
-  # fix "right-hand operand of comma expression has no effect" warning
-  patch -p1 < ../fix-warning-bfd.patch
+  # fix build reproducibility of Windows builds by reverting commit 13e570f80c.
+  # See bug 16472.
+  patch -p1 < ../fix-windows-reproducibility.patch
 [% END -%]
 [% IF c('var/windows-x86_64') -%]
   patch -p1 < ../64bit-fixups.patch
 [% END -%]
-[% IF c("var/linux") && ! c("var/release") -%]
-  # We need to work around a gold linker bug in 2.24 to get selfrando working,
-  # see bug 20683.
-  patch -p1 < $rootdir/binutils-224-gold.patch
-[% END -%]
 ./configure --prefix=$distdir [% c('var/configure_opt') %]
 make -j[% c("buildconf/num_procs") %]
 make install
diff --git a/projects/binutils/config b/projects/binutils/config
index 5c35588..1f992a2 100644
--- a/projects/binutils/config
+++ b/projects/binutils/config
@@ -1,5 +1,5 @@
 # vim: filetype=yaml sw=2
-version: 2.24
+version: 2.26.1
 filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
 var:
   configure_opt: '--disable-multilib --enable-gold --enable-deterministic-archives --enable-plugins'
@@ -10,6 +10,9 @@ targets:
   windows:
     var:
       configure_opt: '--target=[% c("arch") %]-w64-mingw32 --disable-multilib --enable-deterministic-archives'
+      arch_deps:
+        # texinfo required for fix-windows-reproducibility.patch
+        - texinfo
 
 input_files:
   - URL: https://ftp.gnu.org/gnu/binutils/binutils-[% c("version") %].tar.bz2
@@ -19,11 +22,9 @@ input_files:
   - project: container-image
   - filename: enable-reloc-section-ld.patch
     enable: '[% c("var/windows") %]'
-  - filename: fix-warning-bfd.patch
-    enable: '[% c("var/windows") %]'
   - filename: 64bit-fixups.patch
     enable: '[% c("var/windows-x86_64") %]'
   - filename: peXXigen.patch
     enable: '[% c("var/windows") %]'
-  - filename: binutils-224-gold.patch
-    enable: '[% c("var/linux") %]'
+  - filename: fix-windows-reproducibility.patch
+    enable: '[% c("var/windows") %]'
diff --git a/projects/binutils/enable-reloc-section-ld.patch b/projects/binutils/enable-reloc-section-ld.patch
index f393f51..a6600c3 100644
--- a/projects/binutils/enable-reloc-section-ld.patch
+++ b/projects/binutils/enable-reloc-section-ld.patch
@@ -1,30 +1,29 @@
-From 093b08a9e7af23a258306b710ebc4556d12f94f7 Mon Sep 17 00:00:00 2001
+From fba503a78c50d6134943245d55e820f53e8f19cd Mon Sep 17 00:00:00 2001
 From: Erinn Clark <erinn at torproject.org>
 Date: Fri, 8 Aug 2014 14:23:44 -0400
 Subject: [PATCH] add relocation section so Windows bundles can have ASLR
 
 Patch by skruffy.
-
 ---
- ld/emultempl/pe.em  |  6 +++++
- ld/emultempl/pep.em |  8 ++++++-
+ ld/emultempl/pe.em  |  7 ++++++
+ ld/emultempl/pep.em | 11 ++++++++--
  ld/pe-dll.c         | 63 ++++++++++++++++++++++++++++++-----------------------
  ld/pe-dll.h         |  1 +
- 4 files changed, 50 insertions(+), 28 deletions(-)
+ 4 files changed, 53 insertions(+), 29 deletions(-)
 
 diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
-index 5d6da9e..14c07f7 100644
+index 339b7c5..3958b81 100644
 --- a/ld/emultempl/pe.em
 +++ b/ld/emultempl/pe.em
-@@ -268,6 +268,7 @@ fragment <<EOF
- #define OPTION_TERMINAL_SERVER_AWARE	(OPTION_WDM_DRIVER + 1)
- /* Determinism.  */
+@@ -272,6 +272,7 @@ fragment <<EOF
  #define OPTION_INSERT_TIMESTAMP		(OPTION_TERMINAL_SERVER_AWARE + 1)
-+#define OPTION_ENABLE_RELOC_SECTION	(OPTION_INSERT_TIMESTAMP + 1)
+ #define OPTION_NO_INSERT_TIMESTAMP	(OPTION_INSERT_TIMESTAMP + 1)
+ #define OPTION_BUILD_ID			(OPTION_NO_INSERT_TIMESTAMP + 1)
++#define OPTION_ENABLE_RELOC_SECTION	(OPTION_BUILD_ID + 1)
  
  static void
  gld${EMULATION_NAME}_add_options
-@@ -310,6 +311,7 @@ gld${EMULATION_NAME}_add_options
+@@ -315,6 +316,7 @@ gld${EMULATION_NAME}_add_options
      {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL},
      {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
      {"exclude-all-symbols", no_argument, NULL, OPTION_EXCLUDE_ALL_SYMBOLS},
@@ -32,7 +31,7 @@ index 5d6da9e..14c07f7 100644
      {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
      {"exclude-modules-for-implib", required_argument, NULL, OPTION_EXCLUDE_MODULES_FOR_IMPLIB},
      {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
-@@ -773,6 +775,9 @@ gld${EMULATION_NAME}_handle_option (int optc)
+@@ -782,6 +784,9 @@ gld${EMULATION_NAME}_handle_option (int optc)
      case OPTION_EXCLUDE_ALL_SYMBOLS:
        pe_dll_exclude_all_symbols = 1;
        break;
@@ -42,29 +41,30 @@ index 5d6da9e..14c07f7 100644
      case OPTION_EXCLUDE_LIBS:
        pe_dll_add_excludes (optarg, EXCLUDELIBS);
        break;
-@@ -1839,6 +1844,7 @@ gld_${EMULATION_NAME}_finish (void)
-   if (link_info.shared
+@@ -2076,6 +2081,8 @@ gld_${EMULATION_NAME}_finish (void)
  #if !defined(TARGET_IS_shpe)
-       || (!link_info.relocatable && pe_def_file->num_exports != 0)
-+      || (!link_info.relocatable && pe_dll_enable_reloc_section)
+       || (!bfd_link_relocatable (&link_info)
+ 	  && pe_def_file->num_exports != 0)
++      || (!bfd_link_relocatable (&link_info)
++          && pe_dll_enable_reloc_section)
  #endif
      )
      {
 diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
-index b738800..b566903 100644
+index c253d2f..fccbd63 100644
 --- a/ld/emultempl/pep.em
 +++ b/ld/emultempl/pep.em
-@@ -242,7 +242,8 @@ enum options
-   OPTION_NO_BIND,
-   OPTION_WDM_DRIVER,
+@@ -246,7 +246,8 @@ enum options
    OPTION_INSERT_TIMESTAMP,
--  OPTION_TERMINAL_SERVER_AWARE
-+  OPTION_TERMINAL_SERVER_AWARE,
+   OPTION_NO_INSERT_TIMESTAMP,
+   OPTION_TERMINAL_SERVER_AWARE,
+-  OPTION_BUILD_ID
++  OPTION_BUILD_ID,
 +  OPTION_ENABLE_RELOC_SECTION
  };
  
  static void
-@@ -284,6 +285,7 @@ gld${EMULATION_NAME}_add_options
+@@ -288,6 +289,7 @@ gld${EMULATION_NAME}_add_options
      {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL},
      {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
      {"exclude-all-symbols", no_argument, NULL, OPTION_EXCLUDE_ALL_SYMBOLS},
@@ -72,7 +72,7 @@ index b738800..b566903 100644
      {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
      {"exclude-modules-for-implib", required_argument, NULL, OPTION_EXCLUDE_MODULES_FOR_IMPLIB},
      {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
-@@ -727,6 +729,9 @@ gld${EMULATION_NAME}_handle_option (int optc)
+@@ -739,6 +741,9 @@ gld${EMULATION_NAME}_handle_option (int optc)
      case OPTION_EXCLUDE_ALL_SYMBOLS:
        pep_dll_exclude_all_symbols = 1;
        break;
@@ -82,19 +82,22 @@ index b738800..b566903 100644
      case OPTION_EXCLUDE_LIBS:
        pep_dll_add_excludes (optarg, EXCLUDELIBS);
        break;
-@@ -1618,6 +1623,7 @@ gld_${EMULATION_NAME}_finish (void)
- 
+@@ -1857,7 +1862,9 @@ gld_${EMULATION_NAME}_finish (void)
  #ifdef DLL_SUPPORT
-   if (link_info.shared
-+      || (!link_info.relocatable && pe_dll_enable_reloc_section)
-       || (!link_info.relocatable && pep_def_file->num_exports != 0))
+   if (bfd_link_pic (&link_info)
+       || (!bfd_link_relocatable (&link_info)
+-	  && pep_def_file->num_exports != 0))
++          && pe_dll_enable_reloc_section)
++      || (!bfd_link_relocatable (&link_info)
++          && pep_def_file->num_exports != 0))
      {
        pep_dll_fill_sections (link_info.output_bfd, &link_info);
+       if (command_line.out_implib_filename)
 diff --git a/ld/pe-dll.c b/ld/pe-dll.c
-index e9e133b..4230dc3 100644
+index c398f23..3797f1a 100644
 --- a/ld/pe-dll.c
 +++ b/ld/pe-dll.c
-@@ -152,6 +152,7 @@ def_file * pe_def_file = 0;
+@@ -151,6 +151,7 @@ def_file * pe_def_file = 0;
  int pe_dll_export_everything = 0;
  int pe_dll_exclude_all_symbols = 0;
  int pe_dll_do_default_excludes = 1;
@@ -102,10 +105,10 @@ index e9e133b..4230dc3 100644
  int pe_dll_kill_ats = 0;
  int pe_dll_stdcall_aliases = 0;
  int pe_dll_warn_dup_exports = 0;
-@@ -3370,8 +3371,15 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
+@@ -3430,8 +3431,15 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
    process_def_file_and_drectve (abfd, info);
  
-   if (pe_def_file->num_exports == 0 && !info->shared)
+   if (pe_def_file->num_exports == 0 && !bfd_link_pic (info))
 -    return;
 -
 +    {
@@ -120,7 +123,7 @@ index e9e133b..4230dc3 100644
    generate_edata (abfd, info);
    build_filler_bfd (1);
    pe_output_file_set_long_section_names (filler_bfd);
-@@ -3386,13 +3394,9 @@ pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
+@@ -3446,13 +3454,9 @@ pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
    pe_output_file_set_long_section_names (filler_bfd);
  }
  
@@ -136,13 +139,13 @@ index e9e133b..4230dc3 100644
    generate_reloc (abfd, info);
    if (reloc_sz > 0)
      {
-@@ -3409,38 +3413,43 @@ pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
+@@ -3469,38 +3473,43 @@ pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
        lang_do_assignments (lang_final_phase_enum);
      }
  
 -  fill_edata (abfd, info);
 -
--  if (info->shared && !info->pie)
+-  if (bfd_link_dll (info))
 -    pe_data (abfd)->dll = 1;
 -
 -  edata_s->contents = edata_d;
@@ -174,7 +177,7 @@ index e9e133b..4230dc3 100644
 -      /* Resize the sections.  */
 -      lang_reset_memory_regions ();
 -      lang_size_sections (NULL, TRUE);
-+  if (info->shared && !info->pie)
++  if (bfd_link_pic (info) && !bfd_link_pie (info))
 +    pe_data (abfd)->dll = 1;
  
 -      /* Redo special stuff.  */
@@ -200,10 +203,10 @@ index e9e133b..4230dc3 100644
  
  bfd_boolean
 diff --git a/ld/pe-dll.h b/ld/pe-dll.h
-index 4697390..2bf71d9 100644
+index 48d169b..05ff72b 100644
 --- a/ld/pe-dll.h
 +++ b/ld/pe-dll.h
-@@ -31,6 +31,7 @@ extern def_file *pe_def_file;
+@@ -30,6 +30,7 @@ extern def_file *pe_def_file;
  extern int pe_dll_export_everything;
  extern int pe_dll_exclude_all_symbols;
  extern int pe_dll_do_default_excludes;
@@ -212,5 +215,5 @@ index 4697390..2bf71d9 100644
  extern int pe_dll_stdcall_aliases;
  extern int pe_dll_warn_dup_exports;
 -- 
-2.0.1
+2.1.4
 
diff --git a/projects/binutils/fix-warning-bfd.patch b/projects/binutils/fix-warning-bfd.patch
deleted file mode 100644
index fa04405..0000000
--- a/projects/binutils/fix-warning-bfd.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-From 27b829ee701e29804216b3803fbaeb629be27491 Mon Sep 17 00:00:00 2001
-From: Nick Clifton <nickc at redhat.com>
-Date: Wed, 29 Jan 2014 13:46:39 +0000
-Subject: [PATCH] Following up on Tom's suggestion I am checking in a patch to
- replace the various bfd_xxx_set macros with static inline functions, so that
- we can avoid compile time warnings about comma expressions with unused
- values.
-
-	* bfd-in.h (bfd_set_section_vma): Delete.
-	(bfd_set_section_alignment): Delete.
-	(bfd_set_section_userdata): Delete.
-	(bfd_set_cacheable): Delete.
-	* bfd.c (bfd_set_cacheable): New static inline function.
-	* section.c (bfd_set_section_userdata): Likewise.
-	(bfd_set_section_vma): Likewise.
-	(bfd_set_section_alignment): Likewise.
-	* bfd-in2.h: Regenerate.
----
- bfd/bfd-in.h  |  5 -----
- bfd/bfd-in2.h | 41 +++++++++++++++++++++++++++++++++++------
- bfd/bfd.c     |  8 ++++++++
- bfd/section.c | 26 ++++++++++++++++++++++++++
- 5 files changed, 81 insertions(+), 11 deletions(-)
-
-diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
-index 3afd71b..c7c5a7d 100644
---- a/bfd/bfd-in.h
-+++ b/bfd/bfd-in.h
-@@ -292,9 +292,6 @@ typedef struct bfd_section *sec_ptr;
- 
- #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
- 
--#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE)
--#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE)
--#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
- /* Find the address one past the end of SEC.  */
- #define bfd_get_section_limit(bfd, sec) \
-   (((bfd)->direction != write_direction && (sec)->rawsize != 0	\
-@@ -517,8 +514,6 @@ extern void warn_deprecated (const char *, const char *, int, const char *);
- 
- #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
- 
--#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
--
- extern bfd_boolean bfd_cache_close
-   (bfd *abfd);
- /* NB: This declaration should match the autogenerated one in libbfd.h.  */
-diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
-index 71996db..b5aeb40 100644
---- a/bfd/bfd-in2.h
-+++ b/bfd/bfd-in2.h
-@@ -299,9 +299,6 @@ typedef struct bfd_section *sec_ptr;
- 
- #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
- 
--#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE)
--#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE)
--#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
- /* Find the address one past the end of SEC.  */
- #define bfd_get_section_limit(bfd, sec) \
-   (((bfd)->direction != write_direction && (sec)->rawsize != 0	\
-@@ -524,8 +521,6 @@ extern void warn_deprecated (const char *, const char *, int, const char *);
- 
- #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
- 
--#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
--
- extern bfd_boolean bfd_cache_close
-   (bfd *abfd);
- /* NB: This declaration should match the autogenerated one in libbfd.h.  */
-@@ -1029,7 +1024,7 @@ bfd *bfd_openr (const char *filename, const char *target);
- 
- bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
- 
--bfd *bfd_openstreamr (const char *, const char *, void *);
-+bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
- 
- bfd *bfd_openr_iovec (const char *filename, const char *target,
-     void *(*open_func) (struct bfd *nbfd,
-@@ -1596,6 +1591,32 @@ struct relax_table {
-   int size;
- };
- 
-+/* Note: the following are provided as inline functions rather than macros
-+   because not all callers use the return value.  A macro implementation
-+   would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
-+   compilers will complain about comma expressions that have no effect.  */
-+static inline bfd_boolean
-+bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
-+{
-+  ptr->userdata = val;
-+  return TRUE;
-+}
-+
-+static inline bfd_boolean
-+bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
-+{
-+  ptr->vma = ptr->lma = val;
-+  ptr->user_set_vma = TRUE;
-+  return TRUE;
-+}
-+
-+static inline bfd_boolean
-+bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
-+{
-+  ptr->alignment_power = val;
-+  return TRUE;
-+}
-+
- /* These sections are global, and are managed by BFD.  The application
-    and target back end are not permitted to change the values in
-    these sections.  */
-@@ -6415,6 +6436,14 @@ struct bfd
-   unsigned int selective_search : 1;
- };
- 
-+/* See note beside bfd_set_section_userdata.  */
-+static inline bfd_boolean
-+bfd_set_cacheable (bfd * abfd, bfd_boolean val)
-+{
-+  abfd->cacheable = val;
-+  return TRUE;
-+}
-+
- typedef enum bfd_error
- {
-   bfd_error_no_error = 0,
-diff --git a/bfd/bfd.c b/bfd/bfd.c
-index 8d0580c..2d174f3 100644
---- a/bfd/bfd.c
-+++ b/bfd/bfd.c
-@@ -311,6 +311,14 @@ CODE_FRAGMENT
- .  unsigned int selective_search : 1;
- .};
- .
-+.{* See note beside bfd_set_section_userdata.  *}
-+.static inline bfd_boolean
-+.bfd_set_cacheable (bfd * abfd, bfd_boolean val)
-+.{
-+.  abfd->cacheable = val;
-+.  return TRUE;
-+.}
-+.
- */
- 
- #include "sysdep.h"
-diff --git a/bfd/section.c b/bfd/section.c
-index fb19d8c..a661228 100644
---- a/bfd/section.c
-+++ b/bfd/section.c
-@@ -542,6 +542,32 @@ CODE_FRAGMENT
- .  int size;
- .};
- .
-+.{* Note: the following are provided as inline functions rather than macros
-+.   because not all callers use the return value.  A macro implementation
-+.   would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
-+.   compilers will complain about comma expressions that have no effect.  *}
-+.static inline bfd_boolean
-+.bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
-+.{
-+.  ptr->userdata = val;
-+.  return TRUE;
-+.}
-+.
-+.static inline bfd_boolean
-+.bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
-+.{
-+.  ptr->vma = ptr->lma = val;
-+.  ptr->user_set_vma = TRUE;
-+.  return TRUE;
-+.}
-+.
-+.static inline bfd_boolean
-+.bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
-+.{
-+.  ptr->alignment_power = val;
-+.  return TRUE;
-+.}
-+.
- .{* These sections are global, and are managed by BFD.  The application
- .   and target back end are not permitted to change the values in
- .   these sections.  *}
--- 
-2.1.4
-
diff --git a/projects/binutils/fix-windows-reproducibility.patch b/projects/binutils/fix-windows-reproducibility.patch
new file mode 100644
index 0000000..1fc5987
--- /dev/null
+++ b/projects/binutils/fix-windows-reproducibility.patch
@@ -0,0 +1,1034 @@
+From c6df45304e92aa2d7e9f2d8311ae5a0b1543daa8 Mon Sep 17 00:00:00 2001
+From: Nicolas Vigier <boklm at torproject.org>
+Date: Wed, 16 May 2018 11:07:52 +0200
+Subject: [PATCH] Revert "Fix LTO vs. COFF archives"
+
+This reverts commit 13e570f80cbfb299a8858ce6830e91a6cb40ab7b.
+---
+ bfd/aoutx.h     |   2 -
+ bfd/cofflink.c  | 116 +++++++++++++++---
+ bfd/ecoff.c     | 164 +++++++++++++++++++++++--
+ bfd/elflink.c   |  53 ++++++--
+ bfd/libbfd-in.h |   4 +-
+ bfd/libbfd.h    |   4 +-
+ bfd/linker.c    | 366 ++++++++++++++++++++++++++++++++++++++++----------------
+ bfd/pdp11.c     |   4 +-
+ bfd/xcofflink.c |   4 +-
+ 9 files changed, 560 insertions(+), 157 deletions(-)
+
+diff --git a/bfd/aoutx.h b/bfd/aoutx.h
+index 9385a98..6ca9c58 100644
+--- a/bfd/aoutx.h
++++ b/bfd/aoutx.h
+@@ -3405,8 +3405,6 @@ aout_link_check_ar_symbols (bfd *abfd,
+ static bfd_boolean
+ aout_link_check_archive_element (bfd *abfd,
+ 				 struct bfd_link_info *info,
+-				 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+-				 const char *name ATTRIBUTE_UNUSED,
+ 				 bfd_boolean *pneeded)
+ {
+   bfd *oldbfd;
+diff --git a/bfd/cofflink.c b/bfd/cofflink.c
+index 2782795..3a82640 100644
+--- a/bfd/cofflink.c
++++ b/bfd/cofflink.c
+@@ -29,11 +29,9 @@
+ #include "libcoff.h"
+ #include "safe-ctype.h"
+ 
+-static bfd_boolean coff_link_add_object_symbols (bfd *, struct bfd_link_info *);
+-static bfd_boolean coff_link_check_archive_element
+-  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+-   bfd_boolean *);
+-static bfd_boolean coff_link_add_symbols (bfd *, struct bfd_link_info *);
++static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info);
++static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded);
++static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info);
+ 
+ /* Return TRUE if SYM is a weak, external symbol.  */
+ #define IS_WEAK_EXTERNAL(abfd, sym)			\
+@@ -192,6 +190,74 @@ coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+   return TRUE;
+ }
+ 
++/* Look through the symbols to see if this object file should be
++   included in the link.  */
++
++static bfd_boolean
++coff_link_check_ar_symbols (bfd *abfd,
++			    struct bfd_link_info *info,
++			    bfd_boolean *pneeded,
++			    bfd **subsbfd)
++{
++  bfd_size_type symesz;
++  bfd_byte *esym;
++  bfd_byte *esym_end;
++
++  *pneeded = FALSE;
++
++  symesz = bfd_coff_symesz (abfd);
++  esym = (bfd_byte *) obj_coff_external_syms (abfd);
++  esym_end = esym + obj_raw_syment_count (abfd) * symesz;
++  while (esym < esym_end)
++    {
++      struct internal_syment sym;
++      enum coff_symbol_classification classification;
++
++      bfd_coff_swap_sym_in (abfd, esym, &sym);
++
++      classification = bfd_coff_classify_symbol (abfd, &sym);
++      if (classification == COFF_SYMBOL_GLOBAL
++	  || classification == COFF_SYMBOL_COMMON)
++	{
++	  const char *name;
++	  char buf[SYMNMLEN + 1];
++	  struct bfd_link_hash_entry *h;
++
++	  /* This symbol is externally visible, and is defined by this
++             object file.  */
++	  name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
++	  if (name == NULL)
++	    return FALSE;
++	  h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
++
++	  /* Auto import.  */
++	  if (!h
++	      && info->pei386_auto_import
++	      && CONST_STRNEQ (name, "__imp_"))
++	    h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE);
++
++	  /* We are only interested in symbols that are currently
++	     undefined.  If a symbol is currently known to be common,
++	     COFF linkers do not bring in an object file which defines
++	     it.  */
++	  if (h != (struct bfd_link_hash_entry *) NULL
++	      && h->type == bfd_link_hash_undefined)
++	    {
++	      if (!(*info->callbacks
++		    ->add_archive_element) (info, abfd, name, subsbfd))
++		return FALSE;
++	      *pneeded = TRUE;
++	      return TRUE;
++	    }
++	}
++
++      esym += (sym.n_numaux + 1) * symesz;
++    }
++
++  /* We do not need this object file.  */
++  return TRUE;
++}
++
+ /* Check a single archive element to see if we need to include it in
+    the link.  *PNEEDED is set according to whether this element is
+    needed in the link or not.  This is called via
+@@ -200,23 +266,41 @@ coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+ static bfd_boolean
+ coff_link_check_archive_element (bfd *abfd,
+ 				 struct bfd_link_info *info,
+-				 struct bfd_link_hash_entry *h,
+-				 const char *name,
+ 				 bfd_boolean *pneeded)
+ {
+-  *pneeded = FALSE;
++  bfd *oldbfd;
++  bfd_boolean needed;
+ 
+-  /* We are only interested in symbols that are currently undefined.
+-     If a symbol is currently known to be common, COFF linkers do not
+-     bring in an object file which defines it.  */
+-  if (h->type != bfd_link_hash_undefined)
+-    return TRUE;
++  if (!_bfd_coff_get_external_symbols (abfd))
++    return FALSE;
+ 
+-  if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
++  oldbfd = abfd;
++  if (!coff_link_check_ar_symbols (abfd, info, pneeded, &abfd))
+     return FALSE;
+-  *pneeded = TRUE;
+ 
+-  return coff_link_add_object_symbols (abfd, info);
++  needed = *pneeded;
++  if (needed)
++    {
++      /* Potentially, the add_archive_element hook may have set a
++	 substitute BFD for us.  */
++      if (abfd != oldbfd)
++	{
++	  if (!info->keep_memory
++	      && !_bfd_coff_free_symbols (oldbfd))
++	    return FALSE;
++	  if (!_bfd_coff_get_external_symbols (abfd))
++	    return FALSE;
++	}
++      if (!coff_link_add_symbols (abfd, info))
++	return FALSE;
++    }
++
++  if (!info->keep_memory || !needed)
++    {
++      if (!_bfd_coff_free_symbols (abfd))
++	return FALSE;
++    }
++  return TRUE;
+ }
+ 
+ /* Add all the symbols from an object file to the hash table.  */
+diff --git a/bfd/ecoff.c b/bfd/ecoff.c
+index 01f51e6..2c915f0 100644
+--- a/bfd/ecoff.c
++++ b/bfd/ecoff.c
+@@ -3500,29 +3500,171 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+   return FALSE;
+ }
+ 
++/* Factored out from ecoff_link_check_archive_element.  */
++
++static bfd_boolean
++read_ext_syms_and_strs (HDRR **symhdr, bfd_size_type *external_ext_size,
++	bfd_size_type *esize, void **external_ext, char **ssext, bfd *abfd,
++	const struct ecoff_backend_data * const backend)
++{
++  if (! ecoff_slurp_symbolic_header (abfd))
++    return FALSE;
++
++  /* If there are no symbols, we don't want it.  */
++  if (bfd_get_symcount (abfd) == 0)
++    return TRUE;
++
++  *symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
++
++  *external_ext_size = backend->debug_swap.external_ext_size;
++  *esize = (*symhdr)->iextMax * *external_ext_size;
++  *external_ext = bfd_malloc (*esize);
++  if (*external_ext == NULL && *esize != 0)
++    return FALSE;
++
++  if (bfd_seek (abfd, (file_ptr) (*symhdr)->cbExtOffset, SEEK_SET) != 0
++      || bfd_bread (*external_ext, *esize, abfd) != *esize)
++    return FALSE;
++
++  *ssext = (char *) bfd_malloc ((bfd_size_type) (*symhdr)->issExtMax);
++  if (*ssext == NULL && (*symhdr)->issExtMax != 0)
++    return FALSE;
++
++  if (bfd_seek (abfd, (file_ptr) (*symhdr)->cbSsExtOffset, SEEK_SET) != 0
++      || (bfd_bread (*ssext, (bfd_size_type) (*symhdr)->issExtMax, abfd)
++	  != (bfd_size_type) (*symhdr)->issExtMax))
++    return FALSE;
++  return TRUE;
++}
++
++static bfd_boolean
++reread_ext_syms_and_strs (HDRR **symhdr, bfd_size_type *external_ext_size,
++	bfd_size_type *esize, void **external_ext, char **ssext, bfd *abfd,
++	const struct ecoff_backend_data * const backend)
++{
++  if (*external_ext != NULL)
++    free (*external_ext);
++  *external_ext = NULL;
++  if (*ssext != NULL)
++    free (*ssext);
++  *ssext = NULL;
++  return read_ext_syms_and_strs (symhdr, external_ext_size, esize,
++				external_ext, ssext, abfd, backend);
++}
++
+ /* This is called if we used _bfd_generic_link_add_archive_symbols
+    because we were not dealing with an ECOFF archive.  */
+ 
+ static bfd_boolean
+ ecoff_link_check_archive_element (bfd *abfd,
+ 				  struct bfd_link_info *info,
+-				  struct bfd_link_hash_entry *h,
+-				  const char *name,
+ 				  bfd_boolean *pneeded)
+ {
++  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
++  void (* const swap_ext_in) (bfd *, void *, EXTR *)
++    = backend->debug_swap.swap_ext_in;
++  HDRR *symhdr;
++  bfd_size_type external_ext_size = 0;
++  void * external_ext = NULL;
++  bfd_size_type esize = 0;
++  char *ssext = NULL;
++  char *ext_ptr;
++  char *ext_end;
++
+   *pneeded = FALSE;
+ 
+-  /* Unlike the generic linker, we do not pull in elements because
+-     of common symbols.  */
+-  if (h->type != bfd_link_hash_undefined)
+-    return TRUE;
++  /* Read in the external symbols and external strings.  */
++  if (!read_ext_syms_and_strs (&symhdr, &external_ext_size, &esize,
++	&external_ext, &ssext, abfd, backend))
++    goto error_return;
+ 
+-  /* Include this element.  */
+-  if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
+-    return FALSE;
+-  *pneeded = TRUE;
++  /* If there are no symbols, we don't want it.  */
++  if (bfd_get_symcount (abfd) == 0)
++    goto successful_return;
+ 
+-  return ecoff_link_add_object_symbols (abfd, info);
++  /* Look through the external symbols to see if they define some
++     symbol that is currently undefined.  */
++  ext_ptr = (char *) external_ext;
++  ext_end = ext_ptr + esize;
++  for (; ext_ptr < ext_end; ext_ptr += external_ext_size)
++    {
++      EXTR esym;
++      bfd_boolean def;
++      const char *name;
++      bfd *oldbfd;
++      struct bfd_link_hash_entry *h;
++
++      (*swap_ext_in) (abfd, (void *) ext_ptr, &esym);
++
++      /* See if this symbol defines something.  */
++      if (esym.asym.st != stGlobal
++	  && esym.asym.st != stLabel
++	  && esym.asym.st != stProc)
++	continue;
++
++      switch (esym.asym.sc)
++	{
++	case scText:
++	case scData:
++	case scBss:
++	case scAbs:
++	case scSData:
++	case scSBss:
++	case scRData:
++	case scCommon:
++	case scSCommon:
++	case scInit:
++	case scFini:
++	case scRConst:
++	  def = TRUE;
++	  break;
++	default:
++	  def = FALSE;
++	  break;
++	}
++
++      if (! def)
++	continue;
++
++      name = ssext + esym.asym.iss;
++      h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
++
++      /* Unlike the generic linker, we do not pull in elements because
++	 of common symbols.  */
++      if (h == NULL
++	  || h->type != bfd_link_hash_undefined)
++	continue;
++
++      /* Include this element.  */
++      oldbfd = abfd;
++      if (!(*info->callbacks
++	    ->add_archive_element) (info, abfd, name, &abfd))
++	goto error_return;
++      /* Potentially, the add_archive_element hook may have set a
++	 substitute BFD for us.  */
++      if (abfd != oldbfd
++	  && !reread_ext_syms_and_strs (&symhdr, &external_ext_size, &esize,
++					&external_ext, &ssext, abfd, backend))
++	goto error_return;
++      if (! ecoff_link_add_externals (abfd, info, external_ext, ssext))
++	goto error_return;
++
++      *pneeded = TRUE;
++      goto successful_return;
++    }
++
++ successful_return:
++  if (external_ext != NULL)
++    free (external_ext);
++  if (ssext != NULL)
++    free (ssext);
++  return TRUE;
++ error_return:
++  if (external_ext != NULL)
++    free (external_ext);
++  if (ssext != NULL)
++    free (ssext);
++  return FALSE;
+ }
+ 
+ /* Add the symbols from an archive file to the global hash table.
+diff --git a/bfd/elflink.c b/bfd/elflink.c
+index 94ab762..164df6b 100644
+--- a/bfd/elflink.c
++++ b/bfd/elflink.c
+@@ -2933,6 +2933,13 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
+   if (! bfd_check_format (abfd, bfd_object))
+     return FALSE;
+ 
++  /* If we have already included the element containing this symbol in the
++     link then we do not need to include it again.  Just claim that any symbol
++     it contains is not a definition, so that our caller will not decide to
++     (re)include this element.  */
++  if (abfd->archive_pass)
++    return FALSE;
++
+   /* Select the appropriate symbol table.  */
+   if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
+     hdr = &elf_tdata (abfd)->symtab_hdr;
+@@ -4929,8 +4936,20 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd,
+ }
+ 
+ /* Add symbols from an ELF archive file to the linker hash table.  We
+-   don't use _bfd_generic_link_add_archive_symbols because we need to
+-   handle versioned symbols.
++   don't use _bfd_generic_link_add_archive_symbols because of a
++   problem which arises on UnixWare.  The UnixWare libc.so is an
++   archive which includes an entry libc.so.1 which defines a bunch of
++   symbols.  The libc.so archive also includes a number of other
++   object files, which also define symbols, some of which are the same
++   as those defined in libc.so.1.  Correct linking requires that we
++   consider each object file in turn, and include it if it defines any
++   symbols we need.  _bfd_generic_link_add_archive_symbols does not do
++   this; it looks through the list of undefined symbols, and includes
++   any object file which defines them.  When this algorithm is used on
++   UnixWare, it winds up pulling in libc.so.1 early and defining a
++   bunch of symbols.  This means that some of the other objects in the
++   archive are not included in the link, which is incorrect since they
++   precede libc.so.1 in the archive.
+ 
+    Fortunately, ELF archive handling is simpler than that done by
+    _bfd_generic_link_add_archive_symbols, which has to allow for a.out
+@@ -4945,7 +4964,8 @@ static bfd_boolean
+ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+ {
+   symindex c;
+-  unsigned char *included = NULL;
++  bfd_boolean *defined = NULL;
++  bfd_boolean *included = NULL;
+   carsym *symdefs;
+   bfd_boolean loop;
+   bfd_size_type amt;
+@@ -4969,10 +4989,11 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+   if (c == 0)
+     return TRUE;
+   amt = c;
+-  amt *= sizeof (*included);
+-  included = (unsigned char *) bfd_zmalloc (amt);
+-  if (included == NULL)
+-    return FALSE;
++  amt *= sizeof (bfd_boolean);
++  defined = (bfd_boolean *) bfd_zmalloc (amt);
++  included = (bfd_boolean *) bfd_zmalloc (amt);
++  if (defined == NULL || included == NULL)
++    goto error_return;
+ 
+   symdefs = bfd_ardata (abfd)->symdefs;
+   bed = get_elf_backend_data (abfd);
+@@ -4997,7 +5018,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+ 	  struct bfd_link_hash_entry *undefs_tail;
+ 	  symindex mark;
+ 
+-	  if (included[i])
++	  if (defined[i] || included[i])
+ 	    continue;
+ 	  if (symdef->file_offset == last)
+ 	    {
+@@ -5032,8 +5053,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+ 	  else if (h->root.type != bfd_link_hash_undefined)
+ 	    {
+ 	      if (h->root.type != bfd_link_hash_undefweak)
+-		/* Symbol must be defined.  Don't check it again.  */
+-		included[i] = TRUE;
++		defined[i] = TRUE;
+ 	      continue;
+ 	    }
+ 
+@@ -5045,6 +5065,16 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+ 	  if (! bfd_check_format (element, bfd_object))
+ 	    goto error_return;
+ 
++	  /* Doublecheck that we have not included this object
++	     already--it should be impossible, but there may be
++	     something wrong with the archive.  */
++	  if (element->archive_pass != 0)
++	    {
++	      bfd_set_error (bfd_error_bad_value);
++	      goto error_return;
++	    }
++	  element->archive_pass = 1;
++
+ 	  undefs_tail = info->hash->undefs_tail;
+ 
+ 	  if (!(*info->callbacks
+@@ -5082,11 +5112,14 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+     }
+   while (loop);
+ 
++  free (defined);
+   free (included);
+ 
+   return TRUE;
+ 
+  error_return:
++  if (defined != NULL)
++    free (defined);
+   if (included != NULL)
+     free (included);
+   return FALSE;
+diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
+index 50a46ac..90c6018 100644
+--- a/bfd/libbfd-in.h
++++ b/bfd/libbfd-in.h
+@@ -596,9 +596,7 @@ extern bfd_boolean _bfd_generic_link_add_symbols_collect
+ /* Generic archive add symbol routine.  */
+ extern bfd_boolean _bfd_generic_link_add_archive_symbols
+   (bfd *, struct bfd_link_info *,
+-   bfd_boolean (*) (bfd *, struct bfd_link_info *,
+-		    struct bfd_link_hash_entry *, const char *,
+-		    bfd_boolean *));
++   bfd_boolean (*) (bfd *, struct bfd_link_info *, bfd_boolean *));
+ 
+ /* Forward declaration to avoid prototype errors.  */
+ typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
+diff --git a/bfd/libbfd.h b/bfd/libbfd.h
+index 6c48f82..ffb6ea4 100644
+--- a/bfd/libbfd.h
++++ b/bfd/libbfd.h
+@@ -601,9 +601,7 @@ extern bfd_boolean _bfd_generic_link_add_symbols_collect
+ /* Generic archive add symbol routine.  */
+ extern bfd_boolean _bfd_generic_link_add_archive_symbols
+   (bfd *, struct bfd_link_info *,
+-   bfd_boolean (*) (bfd *, struct bfd_link_info *,
+-		    struct bfd_link_hash_entry *, const char *,
+-		    bfd_boolean *));
++   bfd_boolean (*) (bfd *, struct bfd_link_info *, bfd_boolean *));
+ 
+ /* Forward declaration to avoid prototype errors.  */
+ typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
+diff --git a/bfd/linker.c b/bfd/linker.c
+index abdf5b0..4cff1e7 100644
+--- a/bfd/linker.c
++++ b/bfd/linker.c
+@@ -229,16 +229,28 @@ SUBSUBSECTION
+ @findex _bfd_generic_link_add_archive_symbols
+ 	In most cases the work of looking through the symbols in the
+ 	archive should be done by the
+-	<<_bfd_generic_link_add_archive_symbols>> function.
++	<<_bfd_generic_link_add_archive_symbols>> function.  This
++	function builds a hash table from the archive symbol table and
++	looks through the list of undefined symbols to see which
++	elements should be included.
+ 	<<_bfd_generic_link_add_archive_symbols>> is passed a function
+ 	to call to make the final decision about adding an archive
+ 	element to the link and to do the actual work of adding the
+-	symbols to the linker hash table.  If the element is to
++	symbols to the linker hash table.
++
++	The function passed to
++	<<_bfd_generic_link_add_archive_symbols>> must read the
++	symbols of the archive element and decide whether the archive
++	element should be included in the link.  If the element is to
+ 	be included, the <<add_archive_element>> linker callback
+ 	routine must be called with the element as an argument, and
+ 	the element's symbols must be added to the linker hash table
+ 	just as though the element had itself been passed to the
+-	<<_bfd_link_add_symbols>> function.
++	<<_bfd_link_add_symbols>> function.  The <<add_archive_element>>
++	callback has the option to indicate that it would like to
++	replace the element archive with a substitute BFD, in which
++	case it is the symbols of that substitute BFD that must be
++	added to the linker hash table instead.
+ 
+ 	When the a.out <<_bfd_link_add_symbols>> function receives an
+ 	archive, it calls <<_bfd_generic_link_add_archive_symbols>>
+@@ -407,14 +419,11 @@ static bfd_boolean generic_link_add_object_symbols
+ static bfd_boolean generic_link_add_symbols
+   (bfd *, struct bfd_link_info *, bfd_boolean);
+ static bfd_boolean generic_link_check_archive_element_no_collect
+-  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+-   bfd_boolean *);
++  (bfd *, struct bfd_link_info *, bfd_boolean *);
+ static bfd_boolean generic_link_check_archive_element_collect
+-  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+-   bfd_boolean *);
++  (bfd *, struct bfd_link_info *, bfd_boolean *);
+ static bfd_boolean generic_link_check_archive_element
+-  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+-   bfd_boolean *, bfd_boolean);
++  (bfd *, struct bfd_link_info *, bfd_boolean *, bfd_boolean);
+ static bfd_boolean generic_link_add_symbol_list
+   (bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **,
+    bfd_boolean);
+@@ -908,32 +917,138 @@ generic_link_add_object_symbols (bfd *abfd,
+   return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect);
+ }
+ 
++/* We build a hash table of all symbols defined in an archive.  */
++
++/* An archive symbol may be defined by multiple archive elements.
++   This linked list is used to hold the elements.  */
++
++struct archive_list
++{
++  struct archive_list *next;
++  unsigned int indx;
++};
++
++/* An entry in an archive hash table.  */
++
++struct archive_hash_entry
++{
++  struct bfd_hash_entry root;
++  /* Where the symbol is defined.  */
++  struct archive_list *defs;
++};
++
++/* An archive hash table itself.  */
++
++struct archive_hash_table
++{
++  struct bfd_hash_table table;
++};
++
++/* Create a new entry for an archive hash table.  */
++
++static struct bfd_hash_entry *
++archive_hash_newfunc (struct bfd_hash_entry *entry,
++		      struct bfd_hash_table *table,
++		      const char *string)
++{
++  struct archive_hash_entry *ret = (struct archive_hash_entry *) entry;
++
++  /* Allocate the structure if it has not already been allocated by a
++     subclass.  */
++  if (ret == NULL)
++    ret = (struct archive_hash_entry *)
++        bfd_hash_allocate (table, sizeof (struct archive_hash_entry));
++  if (ret == NULL)
++    return NULL;
++
++  /* Call the allocation method of the superclass.  */
++  ret = ((struct archive_hash_entry *)
++	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
++
++  if (ret)
++    {
++      /* Initialize the local fields.  */
++      ret->defs = NULL;
++    }
++
++  return &ret->root;
++}
++
++/* Initialize an archive hash table.  */
++
++static bfd_boolean
++archive_hash_table_init
++  (struct archive_hash_table *table,
++   struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
++				      struct bfd_hash_table *,
++				      const char *),
++   unsigned int entsize)
++{
++  return bfd_hash_table_init (&table->table, newfunc, entsize);
++}
++
++/* Look up an entry in an archive hash table.  */
++
++#define archive_hash_lookup(t, string, create, copy) \
++  ((struct archive_hash_entry *) \
++   bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
++
++/* Allocate space in an archive hash table.  */
++
++#define archive_hash_allocate(t, size) bfd_hash_allocate (&(t)->table, (size))
++
++/* Free an archive hash table.  */
++
++#define archive_hash_table_free(t) bfd_hash_table_free (&(t)->table)
++
+ /* Generic function to add symbols from an archive file to the global
+    hash file.  This function presumes that the archive symbol table
+    has already been read in (this is normally done by the
+-   bfd_check_format entry point).  It looks through the archive symbol
+-   table for symbols that are undefined or common in the linker global
+-   symbol hash table.  When one is found, the CHECKFN argument is used
+-   to see if an object file should be included.  This allows targets
+-   to customize common symbol behaviour.  CHECKFN should set *PNEEDED
+-   to TRUE if the object file should be included, and must also call
+-   the bfd_link_info add_archive_element callback function and handle
+-   adding the symbols to the global hash table.  CHECKFN must notice
+-   if the callback indicates a substitute BFD, and arrange to add
+-   those symbols instead if it does so.  CHECKFN should only return
+-   FALSE if some sort of error occurs.  */
++   bfd_check_format entry point).  It looks through the undefined and
++   common symbols and searches the archive symbol table for them.  If
++   it finds an entry, it includes the associated object file in the
++   link.
++
++   The old linker looked through the archive symbol table for
++   undefined symbols.  We do it the other way around, looking through
++   undefined symbols for symbols defined in the archive.  The
++   advantage of the newer scheme is that we only have to look through
++   the list of undefined symbols once, whereas the old method had to
++   re-search the symbol table each time a new object file was added.
++
++   The CHECKFN argument is used to see if an object file should be
++   included.  CHECKFN should set *PNEEDED to TRUE if the object file
++   should be included, and must also call the bfd_link_info
++   add_archive_element callback function and handle adding the symbols
++   to the global hash table.  CHECKFN must notice if the callback
++   indicates a substitute BFD, and arrange to add those symbols instead
++   if it does so.  CHECKFN should only return FALSE if some sort of
++   error occurs.
++
++   For some formats, such as a.out, it is possible to look through an
++   object file but not actually include it in the link.  The
++   archive_pass field in a BFD is used to avoid checking the symbols
++   of an object files too many times.  When an object is included in
++   the link, archive_pass is set to -1.  If an object is scanned but
++   not included, archive_pass is set to the pass number.  The pass
++   number is incremented each time a new object file is included.  The
++   pass number is used because when a new object file is included it
++   may create new undefined symbols which cause a previously examined
++   object file to be included.  */
+ 
+ bfd_boolean
+ _bfd_generic_link_add_archive_symbols
+   (bfd *abfd,
+    struct bfd_link_info *info,
+-   bfd_boolean (*checkfn) (bfd *, struct bfd_link_info *,
+-			   struct bfd_link_hash_entry *, const char *,
+-			   bfd_boolean *))
++   bfd_boolean (*checkfn) (bfd *, struct bfd_link_info *, bfd_boolean *))
+ {
+-  bfd_boolean loop;
+-  bfd_size_type amt;
+-  unsigned char *included;
++  carsym *arsyms;
++  carsym *arsym_end;
++  register carsym *arsym;
++  int pass;
++  struct archive_hash_table arsym_hash;
++  unsigned int indx;
++  struct bfd_link_hash_entry **pundef;
+ 
+   if (! bfd_has_map (abfd))
+     {
+@@ -944,103 +1059,148 @@ _bfd_generic_link_add_archive_symbols
+       return FALSE;
+     }
+ 
+-  amt = bfd_ardata (abfd)->symdef_count;
+-  if (amt == 0)
+-    return TRUE;
+-  amt *= sizeof (*included);
+-  included = (unsigned char *) bfd_zmalloc (amt);
+-  if (included == NULL)
++  arsyms = bfd_ardata (abfd)->symdefs;
++  arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
++
++  /* In order to quickly determine whether an symbol is defined in
++     this archive, we build a hash table of the symbols.  */
++  if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc,
++				 sizeof (struct archive_hash_entry)))
+     return FALSE;
++  for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
++    {
++      struct archive_hash_entry *arh;
++      struct archive_list *l, **pp;
+ 
+-  do
++      arh = archive_hash_lookup (&arsym_hash, arsym->name, TRUE, FALSE);
++      if (arh == NULL)
++	goto error_return;
++      l = ((struct archive_list *)
++	   archive_hash_allocate (&arsym_hash, sizeof (struct archive_list)));
++      if (l == NULL)
++	goto error_return;
++      l->indx = indx;
++      for (pp = &arh->defs; *pp != NULL; pp = &(*pp)->next)
++	;
++      *pp = l;
++      l->next = NULL;
++    }
++
++  /* The archive_pass field in the archive itself is used to
++     initialize PASS, sine we may search the same archive multiple
++     times.  */
++  pass = abfd->archive_pass + 1;
++
++  /* New undefined symbols are added to the end of the list, so we
++     only need to look through it once.  */
++  pundef = &info->hash->undefs;
++  while (*pundef != NULL)
+     {
+-      carsym *arsyms;
+-      carsym *arsym_end;
+-      carsym *arsym;
+-      unsigned int indx;
+-      file_ptr last_ar_offset = -1;
+-      bfd_boolean needed = FALSE;
+-      bfd *element = NULL;
+-
+-      loop = FALSE;
+-      arsyms = bfd_ardata (abfd)->symdefs;
+-      arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
+-      for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
++      struct bfd_link_hash_entry *h;
++      struct archive_hash_entry *arh;
++      struct archive_list *l;
++
++      h = *pundef;
++
++      /* When a symbol is defined, it is not necessarily removed from
++	 the list.  */
++      if (h->type != bfd_link_hash_undefined
++	  && h->type != bfd_link_hash_common)
+ 	{
+-	  struct bfd_link_hash_entry *h;
+-	  struct bfd_link_hash_entry *undefs_tail;
++	  /* Remove this entry from the list, for general cleanliness
++	     and because we are going to look through the list again
++	     if we search any more libraries.  We can't remove the
++	     entry if it is the tail, because that would lose any
++	     entries we add to the list later on (it would also cause
++	     us to lose track of whether the symbol has been
++	     referenced).  */
++	  if (*pundef != info->hash->undefs_tail)
++	    *pundef = (*pundef)->u.undef.next;
++	  else
++	    pundef = &(*pundef)->u.undef.next;
++	  continue;
++	}
+ 
+-	  if (included[indx])
+-	    continue;
+-	  if (needed && arsym->file_offset == last_ar_offset)
++      /* Look for this symbol in the archive symbol map.  */
++      arh = archive_hash_lookup (&arsym_hash, h->root.string, FALSE, FALSE);
++      if (arh == NULL)
++	{
++	  /* If we haven't found the exact symbol we're looking for,
++	     let's look for its import thunk */
++	  if (info->pei386_auto_import)
++	    {
++	      bfd_size_type amt = strlen (h->root.string) + 10;
++	      char *buf = (char *) bfd_malloc (amt);
++	      if (buf == NULL)
++		return FALSE;
++
++	      sprintf (buf, "__imp_%s", h->root.string);
++	      arh = archive_hash_lookup (&arsym_hash, buf, FALSE, FALSE);
++	      free(buf);
++	    }
++	  if (arh == NULL)
+ 	    {
+-	      included[indx] = 1;
++	      pundef = &(*pundef)->u.undef.next;
+ 	      continue;
+ 	    }
++	}
++      /* Look at all the objects which define this symbol.  */
++      for (l = arh->defs; l != NULL; l = l->next)
++	{
++	  bfd *element;
++	  bfd_boolean needed;
++
++	  /* If the symbol has gotten defined along the way, quit.  */
++	  if (h->type != bfd_link_hash_undefined
++	      && h->type != bfd_link_hash_common)
++	    break;
+ 
+-	  h = bfd_link_hash_lookup (info->hash, arsym->name,
+-				    FALSE, FALSE, TRUE);
++	  element = bfd_get_elt_at_index (abfd, l->indx);
++	  if (element == NULL)
++	    goto error_return;
+ 
+-	  if (h == NULL
+-	      && info->pei386_auto_import
+-	      && CONST_STRNEQ (arsym->name, "__imp_"))
+-	    h = bfd_link_hash_lookup (info->hash, arsym->name + 6,
+-				      FALSE, FALSE, TRUE);
+-	  if (h == NULL)
++	  /* If we've already included this element, or if we've
++	     already checked it on this pass, continue.  */
++	  if (element->archive_pass == -1
++	      || element->archive_pass == pass)
+ 	    continue;
+ 
+-	  if (h->type != bfd_link_hash_undefined
+-	      && h->type != bfd_link_hash_common)
++	  /* If we can't figure this element out, just ignore it.  */
++	  if (! bfd_check_format (element, bfd_object))
+ 	    {
+-	      if (h->type != bfd_link_hash_undefweak)
+-		/* Symbol must be defined.  Don't check it again.  */
+-		included[indx] = 1;
++	      element->archive_pass = -1;
+ 	      continue;
+ 	    }
+ 
+-	  if (last_ar_offset != arsym->file_offset)
+-	    {
+-	      last_ar_offset = arsym->file_offset;
+-	      element = _bfd_get_elt_at_filepos (abfd, last_ar_offset);
+-	      if (element == NULL
+-		  || !bfd_check_format (element, bfd_object))
+-		goto error_return;
+-	    }
+-
+-	  undefs_tail = info->hash->undefs_tail;
+-
+ 	  /* CHECKFN will see if this element should be included, and
+ 	     go ahead and include it if appropriate.  */
+-	  if (! (*checkfn) (element, info, h, arsym->name, &needed))
++	  if (! (*checkfn) (element, info, &needed))
+ 	    goto error_return;
+ 
+-	  if (needed)
++	  if (! needed)
++	    element->archive_pass = pass;
++	  else
+ 	    {
+-	      unsigned int mark;
++	      element->archive_pass = -1;
+ 
+-	      /* Look backward to mark all symbols from this object file
+-		 which we have already seen in this pass.  */
+-	      mark = indx;
+-	      do
+-		{
+-		  included[mark] = 1;
+-		  if (mark == 0)
+-		    break;
+-		  --mark;
+-		}
+-	      while (arsyms[mark].file_offset == last_ar_offset);
+-
+-	      if (undefs_tail != info->hash->undefs_tail)
+-		loop = TRUE;
++	      /* Increment the pass count to show that we may need to
++		 recheck object files which were already checked.  */
++	      ++pass;
+ 	    }
+ 	}
+-    } while (loop);
+ 
+-  free (included);
++      pundef = &(*pundef)->u.undef.next;
++    }
++
++  archive_hash_table_free (&arsym_hash);
++
++  /* Save PASS in case we are called again.  */
++  abfd->archive_pass = pass;
++
+   return TRUE;
+ 
+  error_return:
+-  free (included);
++  archive_hash_table_free (&arsym_hash);
+   return FALSE;
+ }
+ 
+@@ -1050,14 +1210,12 @@ _bfd_generic_link_add_archive_symbols
+    for finding them.  */
+ 
+ static bfd_boolean
+-generic_link_check_archive_element_no_collect (bfd *abfd,
++generic_link_check_archive_element_no_collect (
++					       bfd *abfd,
+ 					       struct bfd_link_info *info,
+-					       struct bfd_link_hash_entry *h,
+-					       const char *name,
+ 					       bfd_boolean *pneeded)
+ {
+-  return generic_link_check_archive_element (abfd, info, h, name, pneeded,
+-					     FALSE);
++  return generic_link_check_archive_element (abfd, info, pneeded, FALSE);
+ }
+ 
+ /* See if we should include an archive element.  This version is used
+@@ -1067,12 +1225,9 @@ generic_link_check_archive_element_no_collect (bfd *abfd,
+ static bfd_boolean
+ generic_link_check_archive_element_collect (bfd *abfd,
+ 					    struct bfd_link_info *info,
+-					    struct bfd_link_hash_entry *h,
+-					    const char *name,
+ 					    bfd_boolean *pneeded)
+ {
+-  return generic_link_check_archive_element (abfd, info, h, name, pneeded,
+-					     TRUE);
++  return generic_link_check_archive_element (abfd, info, pneeded, TRUE);
+ }
+ 
+ /* See if we should include an archive element.  Optionally collect
+@@ -1081,8 +1236,6 @@ generic_link_check_archive_element_collect (bfd *abfd,
+ static bfd_boolean
+ generic_link_check_archive_element (bfd *abfd,
+ 				    struct bfd_link_info *info,
+-				    struct bfd_link_hash_entry *h,
+-				    const char *name ATTRIBUTE_UNUSED,
+ 				    bfd_boolean *pneeded,
+ 				    bfd_boolean collect)
+ {
+@@ -1098,6 +1251,7 @@ generic_link_check_archive_element (bfd *abfd,
+   for (; pp < ppend; pp++)
+     {
+       asymbol *p;
++      struct bfd_link_hash_entry *h;
+ 
+       p = *pp;
+ 
+diff --git a/bfd/pdp11.c b/bfd/pdp11.c
+index 593c5ca..5111a51 100644
+--- a/bfd/pdp11.c
++++ b/bfd/pdp11.c
+@@ -251,7 +251,7 @@ HOWTO( 1,	       0,  1,  16,  TRUE,  0, complain_overflow_signed,0,"DISP16",	TRU
+ #define TABLE_SIZE(TABLE)	(sizeof(TABLE)/sizeof(TABLE[0]))
+ 
+ 
+-static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, bfd_boolean *);
++static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, bfd_boolean *);
+ static bfd_boolean aout_link_add_object_symbols    (bfd *, struct bfd_link_info *);
+ static bfd_boolean aout_link_add_symbols           (bfd *, struct bfd_link_info *);
+ static bfd_boolean aout_link_write_symbols         (struct aout_final_link_info *, bfd *);
+@@ -2682,8 +2682,6 @@ aout_link_check_ar_symbols (bfd *abfd,
+ static bfd_boolean
+ aout_link_check_archive_element (bfd *abfd,
+ 				 struct bfd_link_info *info,
+-				 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+-				 const char *name ATTRIBUTE_UNUSED,
+ 				 bfd_boolean *pneeded)
+ {
+   bfd *oldbfd;
+diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
+index 9522974..dcfd58f 100644
+--- a/bfd/xcofflink.c
++++ b/bfd/xcofflink.c
+@@ -2384,8 +2384,6 @@ xcoff_link_check_ar_symbols (bfd *abfd,
+ static bfd_boolean
+ xcoff_link_check_archive_element (bfd *abfd,
+ 				  struct bfd_link_info *info,
+-				  struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+-				  const char *name ATTRIBUTE_UNUSED,
+ 				  bfd_boolean *pneeded)
+ {
+   bfd_boolean keep_syms_p;
+@@ -2465,7 +2463,7 @@ _bfd_xcoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+ 		bfd_boolean needed;
+ 
+ 		if (! xcoff_link_check_archive_element (member, info,
+-							NULL, NULL, &needed))
++							&needed))
+ 		  return FALSE;
+ 		if (needed)
+ 		  member->archive_pass = -1;
diff --git a/projects/binutils/peXXigen.patch b/projects/binutils/peXXigen.patch
index 785aa02..c2a689a 100644
--- a/projects/binutils/peXXigen.patch
+++ b/projects/binutils/peXXigen.patch
@@ -1,14 +1,29 @@
-diff -crB binutils-2.24/bfd/peXXigen.c binutils-2.24/bfd/peXXigen.c
-*** binutils-2.24/bfd/peXXigen.c	Tue Nov 26 11:37:33 2013
---- binutils-2.24/bfd/peXXigen.c	Mon Aug  4 07:10:15 2014
-***************
-*** 795,800 ****
---- 795,802 ----
-    /* Only use a real timestamp if the option was chosen.  */
-    if ((pe_data (abfd)->insert_timestamp))
-      H_PUT_32 (abfd, time(0), filehdr_out->f_timdat);
-+   else
-+     H_PUT_32 (abfd, 0, filehdr_out->f_timdat);
-  
-    PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
-  		      filehdr_out->f_symptr);
+From f8e8f1daf12e30d3197b25d6bd10c03d1f932e20 Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc at redhat.com>
+Date: Tue, 27 Sep 2016 12:08:19 +0100
+Subject: [PATCH] Ensure that the timestamp in PE/COFF headers is always
+ initialised.
+
+	PR ld/20634
+	* peXXigen.c (_bfd_XXi_only_swap_filehdr_out): Put 0 in the
+	timestamp field if real time values are not being stored.
+---
+ bfd/peXXigen.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
+index c92c1ea..d713d96 100644
+--- a/bfd/peXXigen.c
++++ b/bfd/peXXigen.c
+@@ -879,6 +879,8 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
+   /* Only use a real timestamp if the option was chosen.  */
+   if ((pe_data (abfd)->insert_timestamp))
+     H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
++  else
++    H_PUT_32 (abfd, 0, filehdr_out->f_timdat);
+ 
+   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
+ 		      filehdr_out->f_symptr);
+-- 
+2.1.4
+
diff --git a/projects/mingw-w64/build b/projects/mingw-w64/build
index a142c38..b0ce69d 100644
--- a/projects/mingw-w64/build
+++ b/projects/mingw-w64/build
@@ -29,7 +29,7 @@ sed 's/msvcrt/msvcr100/' -i $distdir/msvcr100.spec
 sed 's/msvcrt/msvcr100/' -i gcc-[% c("var/gcc_version") %]/gcc/config/i386/t-mingw-w32
 # LDFLAGS_FOR_TARGET does not work for some reason. Thus, we take
 # CFLAGS_FOR_TARGET.
-export CFLAGS_FOR_TARGET="-specs=$distdir/msvcr100.spec -Wl,--nxcompat -Wl,--dynamicbase"
+export CFLAGS_FOR_TARGET="-specs=$distdir/msvcr100.spec -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-insert-timestamp"
 gcc-[% c("var/gcc_version") %]/configure --prefix=$distdir --target=[% c("arch") %]-w64-mingw32 --disable-multilib --enable-languages=c,c++
 make -j[% c("buildconf/num_procs") %] all-gcc
 make install-gcc
diff --git a/projects/nsis/build b/projects/nsis/build
index 81ed4d4..5a7b59f 100755
--- a/projects/nsis/build
+++ b/projects/nsis/build
@@ -1,7 +1,6 @@
 #!/bin/bash
 [% c("var/set_default_env") -%]
 [% pc(c('var/compiler'), 'var/setup', { compiler_tarfile => c('input_files_by_name/' _ c('var/compiler')) }) %]
-mkdir -p /var/tmp/dist
 mkdir -p /var/tmp/build
 tar -C /var/tmp/build -xf nsis-[% c('version') %].tar.bz2
 cd /var/tmp/build/nsis-[% c('version') %]-src
@@ -13,7 +12,13 @@ for patch in $(grep '\.patch$' debian/patches/series)
 do
     [ -f debian/patches/$patch ] && patch -p1 < debian/patches/$patch
 done
-[% SET scons_args = 'APPEND_CCFLAGS="-fgnu89-inline" VERSION=' _ c("version") 
+# Adding --no-insert-timestamp to APPEND_LINKFLAGS is not working as it
+# is used for both the host and cross-compiled parts, but this option is
+# only valid for the Windows linker. Therefore we add it using a patch
+# to the cross-compilation part only.
+patch -p1 < $rootdir/no-insert-timestamp.patch
+[% SET scons_args = 'VERSION=' _ c("version")
+        _ ' APPEND_CCFLAGS="-fgnu89-inline"'
         _ " SKIPUTILS='NSIS Menu' XGCC_W32_PREFIX=i686-w64-mingw32-"
         _ ' PREFIX=/var/tmp/dist/nsis' -%]
 scons [% scons_args %]
diff --git a/projects/nsis/config b/projects/nsis/config
index 7db7b60..24adc36 100644
--- a/projects/nsis/config
+++ b/projects/nsis/config
@@ -21,5 +21,6 @@ input_files:
     URL: 'http://http.debian.net/debian/pool/main/n/nsis/nsis_2.51-1.debian.tar.xz'
     sha256sum: 1dee6957b4a4b8dfe69bcf28bc7f301a13b96b3fa5a394e36c8926ae781e774a
   - filename: nsis-missing-unistd-include.patch
+  - filename: no-insert-timestamp.patch
   - name: '[% c("var/compiler") %]'
     project: '[% c("var/compiler") %]'
diff --git a/projects/nsis/no-insert-timestamp.patch b/projects/nsis/no-insert-timestamp.patch
new file mode 100644
index 0000000..e71af21
--- /dev/null
+++ b/projects/nsis/no-insert-timestamp.patch
@@ -0,0 +1,27 @@
+diff -ur nsis-2.51-src/SCons/Config/gnu nsis-2.51-src.n/SCons/Config/gnu
+--- nsis-2.51-src/SCons/Config/gnu	2018-05-24 20:40:06.508000000 +0200
++++ nsis-2.51-src.n/SCons/Config/gnu	2018-05-24 21:04:16.501000000 +0200
+@@ -89,6 +89,7 @@
+ stub_env.Append(LINKFLAGS = ['$ALIGN_FLAG'])        # 512 bytes align
+ stub_env.Append(LINKFLAGS = ['-Wl,-e,_WinMain at 16']) # entry point
+ stub_env.Append(LINKFLAGS = ['$MAP_FLAG'])          # generate map file
++stub_env.Append(LINKFLAGS = ['-Wl,--no-insert-timestamp']) # remove timestamps for reproducible builds
+ 
+ ### makensis environment
+ 
+@@ -125,6 +126,7 @@
+ plugin_env.Append(LINKFLAGS = ['$MAP_FLAG'])        # generate map file
+ plugin_env.Append(LINKFLAGS = ['-static-libgcc'])   # Make sure libgcc is statically linked in, for the plugins to work.
+ plugin_env.Append(LINKFLAGS = ['-static-libstdc++']) # Make sure libstdc++ is statically linked in, for the plugins to work.
++plugin_env.Append(LINKFLAGS = ['-Wl,--no-insert-timestamp']) # remove timestamps for reproducible builds
+ 
+ ### cross-platform util environment
+ 
+@@ -148,6 +150,7 @@
+ 
+ util_env.Append(LINKFLAGS = ['-mwindows'])          # build windows executables
+ util_env.Append(LINKFLAGS = ['$ALIGN_FLAG'])        # 512 bytes align
++util_env.Append(LINKFLAGS = ['-Wl,--no-insert-timestamp']) # remove timestamps for reproducible builds
+ 
+ conf = FlagsConfigure(util_env)
+ if not defenv['DEBUG'] and defenv['STRIP'] and defenv['STRIP_W32']:
diff --git a/projects/openssl/config b/projects/openssl/config
index 9ab54c6..9c191fa 100644
--- a/projects/openssl/config
+++ b/projects/openssl/config
@@ -15,7 +15,7 @@ targets:
       configure_opts: -shared linux-generic32
   windows:
     var:
-      configure_opts: '-shared --cross-compile-prefix=[% c("arch") %]-w64-mingw32- mingw[% IF c("var/windows-x86_64") %]64[% END %] "-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -lssp -L$gcclibs"'
+      configure_opts: '-shared --cross-compile-prefix=[% c("arch") %]-w64-mingw32- mingw[% IF c("var/windows-x86_64") %]64[% END %] "-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp -lssp -L$gcclibs"'
   osx-x86_64:
     var:
       configure_opts: --cross-compile-prefix=x86_64-apple-darwin10- darwin64-x86_64-cc enable-ec_nistp_64_gcc_128
diff --git a/projects/selfrando/config b/projects/selfrando/config
index f8afa5d..07195f7 100644
--- a/projects/selfrando/config
+++ b/projects/selfrando/config
@@ -1,6 +1,6 @@
 # vim: filetype=yaml sw=2
 filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
-version: 0.3.3
+version: 0.4.1
 git_hash: 'tb-v[% c("version") %]'
 git_url: https://github.com/immunant/selfrando.git
 gpg_keyring: selfrando.gpg
diff --git a/projects/zlib/build b/projects/zlib/build
index 4cb384b..ef26882 100644
--- a/projects/zlib/build
+++ b/projects/zlib/build
@@ -7,8 +7,8 @@ tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
 cd /var/tmp/build/[% project %]-[% c('version') %]
 export CFLAGS="[% c("var/CFLAGS") %]"
 export LDFLAGS="[% c("var/LDFLAGS") %]"
-make BINARY_PATH=$distdir/lib INCLUDE_PATH=$distdir/include LIBRARY_PATH=$distdir/lib -f win32/Makefile.gcc PREFIX=[% c("arch") %]-w64-mingw32- -j4 SHARED_MODE=1 LOC="-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -lssp -L$gcclibs"
-make BINARY_PATH=$distdir/lib INCLUDE_PATH=$distdir/include LIBRARY_PATH=$distdir/lib -f win32/Makefile.gcc PREFIX=[% c("arch") %]-w64-mingw32- -j4 SHARED_MODE=1 LOC="-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -lssp -L$gcclibs" install
+make BINARY_PATH=$distdir/lib INCLUDE_PATH=$distdir/include LIBRARY_PATH=$distdir/lib -f win32/Makefile.gcc PREFIX=[% c("arch") %]-w64-mingw32- -j4 SHARED_MODE=1 LOC="-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp -lssp -L$gcclibs"
+make BINARY_PATH=$distdir/lib INCLUDE_PATH=$distdir/include LIBRARY_PATH=$distdir/lib -f win32/Makefile.gcc PREFIX=[% c("arch") %]-w64-mingw32- -j4 SHARED_MODE=1 LOC="-fstack-protector-all -Wstack-protector --param ssp-buffer-size=4 -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp -lssp -L$gcclibs" install
 
 cd /var/tmp/dist
 [% c('tar', {
diff --git a/rbm.conf b/rbm.conf
index 6adcd6f..0d6de69 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -217,7 +217,7 @@ targets:
         suite: jessie
       configure_opt: '--host=[% c("arch") %]-w64-mingw32 CFLAGS="[% c("var/CFLAGS") %]" LDFLAGS="[% c("var/LDFLAGS") %]"'
       CFLAGS: '[% c("var/flag_mwindows") %] -fstack-protector-strong -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security'
-      LDFLAGS: '[% c("var/flag_mwindows") %] -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -lssp -L$gcclibs'
+      LDFLAGS: '[% c("var/flag_mwindows") %] -Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp -lssp -L$gcclibs'
       flag_mwindows: '-mwindows'
       compiler: mingw-w64
       deps:





More information about the tor-commits mailing list