Roll binutils to 2.29.1

BUG=793797
[email protected],[email protected]
[email protected]

Change-Id: I04180e7a59f02b7492cc63159ecf17b7b87cf7f0
Reviewed-on: https://chromium-review.googlesource.com/820293
Reviewed-by: Lei Zhang <[email protected]>
Commit-Queue: Thomas Anderson <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#523294}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 07ea4ec40d4b978fd04612956342e126a7a02041
diff --git a/Linux_ia32/binutils.tar.bz2.sha1 b/Linux_ia32/binutils.tar.bz2.sha1
index 93942d8..f4ad943 100644
--- a/Linux_ia32/binutils.tar.bz2.sha1
+++ b/Linux_ia32/binutils.tar.bz2.sha1
@@ -1 +1 @@
-81fd042fef3e2ff2e807a8c1fb4ea621b665d6b3
\ No newline at end of file
+ee534836babdf330503ad62934a1975fc9b6fba9
\ No newline at end of file
diff --git a/Linux_x64/binutils.tar.bz2.sha1 b/Linux_x64/binutils.tar.bz2.sha1
index 6bc9f8c..bef9452 100644
--- a/Linux_x64/binutils.tar.bz2.sha1
+++ b/Linux_x64/binutils.tar.bz2.sha1
@@ -1 +1 @@
-dbe488f8a5c2e11573a38e8b01e8c96bebed3365
\ No newline at end of file
+5230f6066998df2f4d61d5fa586152ab20cca300
\ No newline at end of file
diff --git a/README.chromium b/README.chromium
index 92380ac..813cf68 100644
--- a/README.chromium
+++ b/README.chromium
@@ -1,6 +1,6 @@
 Name: binutils
 URL: http://www.gnu.org/software/binutils/
-Version: 2.28
+Version: 2.29.1
 License: GPL v2
 License File: NOT_SHIPPED
 Security Critical: no
@@ -9,14 +9,12 @@
 This directory contains i386 and amd64 binaries of the binutils tools
 (including gold linker).
 
-They were built from binutils-2.28 using the "build-all.sh" script on Debian
+They were built from binutils-2.29.1 using the "build-all.sh" script on Debian
 Testing.
 
 The script creates chroots for 32bit and 64bit Ubuntu Xenial and then builds
 binutils inside the roots.
 
-Version 2.28 was released on Thu, 02 Mar 2017
-
 Local patches:
 
  * (build-all.sh|build-one.sh|upload.sh) scripts for building the binutils
diff --git a/build-all.sh b/build-all.sh
index 2439c58..5845a12 100755
--- a/build-all.sh
+++ b/build-all.sh
@@ -23,7 +23,7 @@
 fi
 
 # Download the source
-VERSION=2.28
+VERSION=2.29.1
 wget -c http://ftp.gnu.org/gnu/binutils/binutils-$VERSION.tar.bz2
 
 # Verify the signature
@@ -32,7 +32,7 @@
   echo "GPG Signature failed to verify."
   echo ""
   echo "You may need to import the vendor GPG key with:"
-  echo "# gpg --keyserver hkp://pgp.mit.edu:80 --recv-key 4AE55E93"
+  echo "# gpg --keyserver hkp://pgp.mit.edu:80 --recv-key 4AE55E93 DD9E3C4F"
   exit 1
 fi
 
diff --git a/icf-align.patch b/icf-align.patch
deleted file mode 100644
index 719f019..0000000
--- a/icf-align.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-commit ac423761af22f7858a1413cda5df3e1d5e88d4e4
-Author: Gergely Nagy <[email protected]>
-Date:   Fri Oct 21 11:08:20 2016 -0700
-
-    Fix PR 17704.
-    
-    This fix keeps the section with the highest alignment when folding sections with ICF.
-    
-            PR gold/17704
-            * icf.cc (match_sections): Add new parameter section_addraligns.
-            Check section alignment and keep the section with the strictest
-            alignment.
-            (find_identical_sections): New local variable section_addraligns.
-            Store each section's alignment.
-            * testsuite/pr17704a_test.s: New file.
-            * testsuite/Makefile.am (pr17704a_test): New test.
-            * testsuite/Makefile.in: Regenerate.
-
-diff --git a/gold/icf.cc b/gold/icf.cc
-index dce0b8b3e2..c09c746ae1 100644
---- a/gold/icf.cc
-+++ b/gold/icf.cc
-@@ -590,6 +590,7 @@ match_sections(unsigned int iteration_num,
-                std::vector<unsigned int>* num_tracked_relocs,
-                std::vector<unsigned int>* kept_section_id,
-                const std::vector<Section_id>& id_section,
-+	       const std::vector<uint64_t>& section_addraligns,
-                std::vector<bool>* is_secn_or_group_unique,
-                std::vector<std::string>* section_contents)
- {
-@@ -630,13 +631,7 @@ match_sections(unsigned int iteration_num,
-         {
-           if ((*kept_section_id)[i] != i)
-             {
--              // This section is already folded into something.  See
--              // if it should point to a different kept section.
--              unsigned int kept_section = (*kept_section_id)[i];
--              if (kept_section != (*kept_section_id)[kept_section])
--                {
--                  (*kept_section_id)[i] = (*kept_section_id)[kept_section];
--                }
-+              // This section is already folded into something.
-               continue;
-             }
-           this_secn_contents = get_section_contents(false, secn, i, NULL,
-@@ -671,7 +666,25 @@ match_sections(unsigned int iteration_num,
-                          this_secn_contents.c_str(),
-                          this_secn_contents.length()) != 0)
-                   continue;
--              (*kept_section_id)[i] = kept_section;
-+
-+	      // Check section alignment here.
-+	      // The section with the larger alignment requirement
-+	      // should be kept.  We assume alignment can only be 
-+	      // zero or postive integral powers of two.
-+	      uint64_t align_i = section_addraligns[i];
-+	      uint64_t align_kept = section_addraligns[kept_section];
-+	      if (align_i <= align_kept)
-+		{
-+		  (*kept_section_id)[i] = kept_section;
-+		}
-+	      else
-+		{
-+		  (*kept_section_id)[kept_section] = i;
-+		  it->second = i;
-+		  full_section_contents[kept_section].swap(
-+		      full_section_contents[i]);
-+		}
-+
-               converged = false;
-               break;
-             }
-@@ -688,6 +701,26 @@ match_sections(unsigned int iteration_num,
-         (*is_secn_or_group_unique)[i] = true;
-     }
- 
-+  // If a section was folded into another section that was later folded
-+  // again then the former has to be updated.
-+  for (unsigned int i = 0; i < id_section.size(); i++)
-+    {
-+      // Find the end of the folding chain
-+      unsigned int kept = i;
-+      while ((*kept_section_id)[kept] != kept)
-+        {
-+          kept = (*kept_section_id)[kept];
-+        }
-+      // Update every element of the chain
-+      unsigned int current = i;
-+      while ((*kept_section_id)[current] != kept)
-+        {
-+          unsigned int next = (*kept_section_id)[current];
-+          (*kept_section_id)[current] = kept;
-+          current = next;
-+        }
-+    }
-+
-   return converged;
- }
- 
-@@ -719,6 +752,7 @@ Icf::find_identical_sections(const Input_objects* input_objects,
- {
-   unsigned int section_num = 0;
-   std::vector<unsigned int> num_tracked_relocs;
-+  std::vector<uint64_t> section_addraligns;
-   std::vector<bool> is_secn_or_group_unique;
-   std::vector<std::string> section_contents;
-   const Target& target = parameters->target();
-@@ -759,6 +793,7 @@ Icf::find_identical_sections(const Input_objects* input_objects,
-           this->section_id_[Section_id(*p, i)] = section_num;
-           this->kept_section_id_.push_back(section_num);
-           num_tracked_relocs.push_back(0);
-+	  section_addraligns.push_back((*p)->section_addralign(i));
-           is_secn_or_group_unique.push_back(false);
-           section_contents.push_back("");
-           section_num++;
-@@ -779,8 +814,8 @@ Icf::find_identical_sections(const Input_objects* input_objects,
-       num_iterations++;
-       converged = match_sections(num_iterations, symtab,
-                                  &num_tracked_relocs, &this->kept_section_id_,
--                                 this->id_section_, &is_secn_or_group_unique,
--                                 &section_contents);
-+                                 this->id_section_, section_addraligns,
-+                                 &is_secn_or_group_unique, &section_contents);
-     }
- 
-   if (parameters->options().print_icf_sections())
diff --git a/icf-rel.patch b/icf-rel.patch
deleted file mode 100644
index 1747fcc..0000000
--- a/icf-rel.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-commit d114b830426300f80302ca03ff4322942f63c615
-Author: Roland McGrath <[email protected]>
-Date:   Thu May 5 13:12:40 2016 -0700
-
-    2016-02-05  Sriraman Tallam  <[email protected]>
-    
-    	PR gold/19047
-    	* icf.cc (get_rel_addend): New function.
-    	(get_section_contents):  Move merge section addend computation to a
-    	new function.  Ignore negative values for SHT_REL and SHT_RELA addends.
-    	Fix bug to not read past the length of the section.
-    
-    Fix bug related to addend computation for MERGE sections.
-    
-    (cherry picked from commit 84d543b7ed93bf6511cdf45791f4f0b717dfb718)
-
-diff --git a/gold/ChangeLog b/gold/ChangeLog
-index 92b26ba..ec8dacb 100644
---- a/gold/ChangeLog
-+++ b/gold/ChangeLog
-@@ -1,3 +1,11 @@
-+2016-02-05  Sriraman Tallam  <[email protected]>
-+
-+	PR gold/19047
-+	* icf.cc (get_rel_addend): New function.
-+	(get_section_contents):  Move merge section addend computation to a
-+	new function.  Ignore negative values for SHT_REL and SHT_RELA addends.
-+	Fix bug to not read past the length of the section.
-+
- 2015-12-17  Peter Collingbourne  <[email protected]>
-
-	 PR gold/18780
-diff --git a/gold/icf.cc b/gold/icf.cc
-index 96b7f2d..663d579 100644
---- a/gold/icf.cc
-+++ b/gold/icf.cc
-@@ -213,6 +213,45 @@ preprocess_for_unique_sections(const std::vector<Section_id>& id_section,
-     }
- }
- 
-+// For SHF_MERGE sections that use REL relocations, the addend is stored in
-+// the text section at the relocation offset.  Read  the addend value given
-+// the pointer to the addend in the text section and the addend size.
-+// Update the addend value if a valid addend is found.
-+// Parameters:
-+// RELOC_ADDEND_PTR   : Pointer to the addend in the text section.
-+// ADDEND_SIZE        : The size of the addend.
-+// RELOC_ADDEND_VALUE : Pointer to the addend that is updated.
-+
-+inline void
-+get_rel_addend(const unsigned char* reloc_addend_ptr,
-+	       const unsigned int addend_size,
-+	       uint64_t* reloc_addend_value)
-+{
-+  switch (addend_size)
-+    {
-+    case 0:
-+      break;
-+    case 1:
-+      *reloc_addend_value =
-+        read_from_pointer<8>(reloc_addend_ptr);
-+      break;
-+    case 2:
-+      *reloc_addend_value =
-+          read_from_pointer<16>(reloc_addend_ptr);
-+      break;
-+    case 4:
-+      *reloc_addend_value =
-+        read_from_pointer<32>(reloc_addend_ptr);
-+      break;
-+    case 8:
-+      *reloc_addend_value =
-+        read_from_pointer<64>(reloc_addend_ptr);
-+      break;
-+    default:
-+      gold_unreachable();
-+    }
-+}
-+
- // This returns the buffer containing the section's contents, both
- // text and relocs.  Relocs are differentiated as those pointing to
- // sections that could be folded and those that cannot.  Only relocs
-@@ -397,58 +436,36 @@ get_section_contents(bool first_iteration,
-                   uint64_t entsize =
-                     (it_v->first)->section_entsize(it_v->second);
- 		  long long offset = it_a->first;
--
--                  unsigned long long addend = it_a->second;
--                  // Ignoring the addend when it is a negative value.  See the 
--                  // comments in Merged_symbol_value::Value in object.h.
--                  if (addend < 0xffffff00)
--                    offset = offset + addend;
--
--		  // For SHT_REL relocation sections, the addend is stored in the
--		  // text section at the relocation offset.
--		  uint64_t reloc_addend_value = 0;
-+		  // Handle SHT_RELA and SHT_REL addends, only one of these
-+		  // addends exists.
-+		  // Get the SHT_RELA addend.  For RELA relocations, we have
-+		  // the addend from the relocation.
-+		  uint64_t reloc_addend_value = it_a->second;
-+
-+		  // Handle SHT_REL addends.
-+		  // For REL relocations, we need to fetch the addend from the
-+		  // section contents.
-                   const unsigned char* reloc_addend_ptr =
- 		    contents + static_cast<unsigned long long>(*it_o);
--		  switch(*it_addend_size)
--		    {
--		      case 0:
--		        {
--                          break;
--                        }
--                      case 1:
--                        {
--                          reloc_addend_value =
--                            read_from_pointer<8>(reloc_addend_ptr);
--			  break;
--                        }
--                      case 2:
--                        {
--                          reloc_addend_value =
--                            read_from_pointer<16>(reloc_addend_ptr);
--			  break;
--                        }
--                      case 4:
--                        {
--                          reloc_addend_value =
--                            read_from_pointer<32>(reloc_addend_ptr);
--			  break;
--                        }
--                      case 8:
--                        {
--                          reloc_addend_value =
--                            read_from_pointer<64>(reloc_addend_ptr);
--			  break;
--                        }
--		      default:
--		        gold_unreachable();
--		    }
--		  offset = offset + reloc_addend_value;
-+
-+		  // Update the addend value with the SHT_REL addend if
-+		  // available.
-+		  get_rel_addend(reloc_addend_ptr, *it_addend_size,
-+				 &reloc_addend_value);
-+
-+		  // Ignore the addend when it is a negative value.  See the
-+		  // comments in Merged_symbol_value::value in object.h.
-+		  if (reloc_addend_value < 0xffffff00)
-+		    offset = offset + reloc_addend_value;
- 
-                   section_size_type secn_len;
-+
-                   const unsigned char* str_contents =
-                   (it_v->first)->section_contents(it_v->second,
-                                                   &secn_len,
-                                                   false) + offset;
-+		  gold_assert (offset < (long long) secn_len);
-+
-                   if ((secn_flags & elfcpp::SHF_STRINGS) != 0)
-                     {
-                       // String merge section.
-@@ -489,10 +506,14 @@ get_section_contents(bool first_iteration,
-                     }
-                   else
-                     {
--                      // Use the entsize to determine the length.
--                      buffer.append(reinterpret_cast<const 
-+                      // Use the entsize to determine the length to copy.
-+		      uint64_t bufsize = entsize;
-+		      // If entsize is too big, copy all the remaining bytes.
-+		      if ((offset + entsize) > secn_len)
-+			bufsize = secn_len - offset;
-+                      buffer.append(reinterpret_cast<const
-                                                      char*>(str_contents),
--                                    entsize);
-+                                    bufsize);
-                     }
- 		  buffer.append("@");
-                 }
diff --git a/long-plt.patch b/long-plt.patch
deleted file mode 100644
index 4738eea..0000000
--- a/long-plt.patch
+++ /dev/null
@@ -1,260 +0,0 @@
-commit ce3e49806d505721e0875e704de0b6fcba7660ed
-Author: Peter Collingbourne <[email protected]>
-Date:   Thu Dec 17 16:50:35 2015 -0800
-
-    Implement --long-plt flag (ARM only).
-    
-    gold/
-        PR gold/18780
-        * arm.cc (Target_arm::do_make_data_plt): Choose PLT generator based
-        on value of --long-plt flag.
-        (Output_data_plt_arm_standard::do_get_plt_entry_size): Moved to
-        Output_data_plt_arm_short.
-        (Output_data_plt_arm_standard::do_fill_plt_entry): Likewise.
-        (Output_data_plt_arm_standard::plt_entry): Likewise.
-        (Output_data_plt_arm_standard::do_fill_first_plt_entry): Fix
-        variable reference.
-        (Output_data_plt_arm_short): New class.
-        (Output_data_plt_arm_short::do_fill_plt_entry): Error out on too large
-        PLT offsets instead of asserting.
-        (Output_data_plt_arm_long): New class.
-        * options.h (General_options): Define --long-plt flag.
-
-diff --git a/gold/ChangeLog b/gold/ChangeLog
-index d929cb7..07589c9 100644
---- a/gold/ChangeLog
-+++ b/gold/ChangeLog
-@@ -1,3 +1,20 @@
-+2015-12-17  Peter Collingbourne  <[email protected]>
-+
-+	PR gold/18780
-+	* arm.cc (Target_arm::do_make_data_plt): Choose PLT generator based
-+	on value of --long-plt flag.
-+	(Output_data_plt_arm_standard::do_get_plt_entry_size): Moved to
-+	Output_data_plt_arm_short.
-+	(Output_data_plt_arm_standard::do_fill_plt_entry): Likewise.
-+	(Output_data_plt_arm_standard::plt_entry): Likewise.
-+	(Output_data_plt_arm_standard::do_fill_first_plt_entry): Fix
-+	variable reference.
-+	(Output_data_plt_arm_short): New class.
-+	(Output_data_plt_arm_short::do_fill_plt_entry): Error out on too large
-+	PLT offsets instead of asserting.
-+	(Output_data_plt_arm_long): New class.
-+	* options.h (General_options): Define --long-plt flag.
-+
- 2015-12-16  Roland McGrath  <[email protected]>
- 
- 	PR ld/17473
-diff --git a/gold/arm.cc b/gold/arm.cc
-index 33e8734..fc387bb 100644
---- a/gold/arm.cc
-+++ b/gold/arm.cc
-@@ -62,7 +62,10 @@ template<bool big_endian>
- class Output_data_plt_arm;
- 
- template<bool big_endian>
--class Output_data_plt_arm_standard;
-+class Output_data_plt_arm_short;
-+
-+template<bool big_endian>
-+class Output_data_plt_arm_long;
- 
- template<bool big_endian>
- class Stub_table;
-@@ -2554,7 +2557,11 @@ class Target_arm : public Sized_target<32, big_endian>
- 		   Output_data_space* got_irelative)
-   {
-     gold_assert(got_plt != NULL && got_irelative != NULL);
--    return new Output_data_plt_arm_standard<big_endian>(
-+    if (parameters->options().long_plt())
-+      return new Output_data_plt_arm_long<big_endian>(
-+	layout, got, got_plt, got_irelative);
-+    else
-+      return new Output_data_plt_arm_short<big_endian>(
- 	layout, got, got_plt, got_irelative);
-   }
- 
-@@ -7715,29 +7722,14 @@ class Output_data_plt_arm_standard : public Output_data_plt_arm<big_endian>
-   do_first_plt_entry_offset() const
-   { return sizeof(first_plt_entry); }
- 
--  // Return the size of a PLT entry.
--  virtual unsigned int
--  do_get_plt_entry_size() const
--  { return sizeof(plt_entry); }
--
-   virtual void
-   do_fill_first_plt_entry(unsigned char* pov,
- 			  Arm_address got_address,
- 			  Arm_address plt_address);
- 
--  virtual void
--  do_fill_plt_entry(unsigned char* pov,
--		    Arm_address got_address,
--		    Arm_address plt_address,
--		    unsigned int got_offset,
--		    unsigned int plt_offset);
--
-  private:
-   // Template for the first PLT entry.
-   static const uint32_t first_plt_entry[5];
--
--  // Template for subsequent PLT entries.
--  static const uint32_t plt_entry[3];
- };
- 
- // ARM PLTs.
-@@ -7765,7 +7757,7 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry(
- {
-   // Write first PLT entry.  All but the last word are constants.
-   const size_t num_first_plt_words = (sizeof(first_plt_entry)
--				      / sizeof(plt_entry[0]));
-+				      / sizeof(first_plt_entry[0]));
-   for (size_t i = 0; i < num_first_plt_words - 1; i++)
-     elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
-   // Last word in first PLT entry is &GOT[0] - .
-@@ -7774,9 +7766,39 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry(
- }
- 
- // Subsequent entries in the PLT.
-+// This class generates short (12-byte) entries, for displacements up to 2^28.
- 
- template<bool big_endian>
--const uint32_t Output_data_plt_arm_standard<big_endian>::plt_entry[3] =
-+class Output_data_plt_arm_short : public Output_data_plt_arm_standard<big_endian>
-+{
-+ public:
-+  Output_data_plt_arm_short(Layout* layout,
-+			    Arm_output_data_got<big_endian>* got,
-+			    Output_data_space* got_plt,
-+			    Output_data_space* got_irelative)
-+    : Output_data_plt_arm_standard<big_endian>(layout, got, got_plt, got_irelative)
-+  { }
-+
-+ protected:
-+  // Return the size of a PLT entry.
-+  virtual unsigned int
-+  do_get_plt_entry_size() const
-+  { return sizeof(plt_entry); }
-+
-+  virtual void
-+  do_fill_plt_entry(unsigned char* pov,
-+		    Arm_address got_address,
-+		    Arm_address plt_address,
-+		    unsigned int got_offset,
-+		    unsigned int plt_offset);
-+
-+ private:
-+  // Template for subsequent PLT entries.
-+  static const uint32_t plt_entry[3];
-+};
-+
-+template<bool big_endian>
-+const uint32_t Output_data_plt_arm_short<big_endian>::plt_entry[3] =
- {
-   0xe28fc600,	// add   ip, pc, #0xNN00000
-   0xe28cca00,	// add   ip, ip, #0xNN000
-@@ -7785,7 +7807,7 @@ const uint32_t Output_data_plt_arm_standard<big_endian>::plt_entry[3] =
- 
- template<bool big_endian>
- void
--Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
-+Output_data_plt_arm_short<big_endian>::do_fill_plt_entry(
-     unsigned char* pov,
-     Arm_address got_address,
-     Arm_address plt_address,
-@@ -7794,8 +7816,9 @@ Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
- {
-   int32_t offset = ((got_address + got_offset)
- 		    - (plt_address + plt_offset + 8));
-+  if (offset < 0 || offset > 0x0fffffff)
-+    gold_error(_("PLT offset too large, try linking with --long-plt"));
- 
--  gold_assert(offset >= 0 && offset < 0x0fffffff);
-   uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff);
-   elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
-   uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff);
-@@ -7804,6 +7827,68 @@ Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
-   elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
- }
- 
-+// This class generates long (16-byte) entries, for arbitrary displacements.
-+
-+template<bool big_endian>
-+class Output_data_plt_arm_long : public Output_data_plt_arm_standard<big_endian>
-+{
-+ public:
-+  Output_data_plt_arm_long(Layout* layout,
-+			   Arm_output_data_got<big_endian>* got,
-+			   Output_data_space* got_plt,
-+			   Output_data_space* got_irelative)
-+    : Output_data_plt_arm_standard<big_endian>(layout, got, got_plt, got_irelative)
-+  { }
-+
-+ protected:
-+  // Return the size of a PLT entry.
-+  virtual unsigned int
-+  do_get_plt_entry_size() const
-+  { return sizeof(plt_entry); }
-+
-+  virtual void
-+  do_fill_plt_entry(unsigned char* pov,
-+		    Arm_address got_address,
-+		    Arm_address plt_address,
-+		    unsigned int got_offset,
-+		    unsigned int plt_offset);
-+
-+ private:
-+  // Template for subsequent PLT entries.
-+  static const uint32_t plt_entry[4];
-+};
-+
-+template<bool big_endian>
-+const uint32_t Output_data_plt_arm_long<big_endian>::plt_entry[4] =
-+{
-+  0xe28fc200,	// add   ip, pc, #0xN0000000
-+  0xe28cc600,	// add   ip, ip, #0xNN00000
-+  0xe28cca00,	// add   ip, ip, #0xNN000
-+  0xe5bcf000,	// ldr   pc, [ip, #0xNNN]!
-+};
-+
-+template<bool big_endian>
-+void
-+Output_data_plt_arm_long<big_endian>::do_fill_plt_entry(
-+    unsigned char* pov,
-+    Arm_address got_address,
-+    Arm_address plt_address,
-+    unsigned int got_offset,
-+    unsigned int plt_offset)
-+{
-+  int32_t offset = ((got_address + got_offset)
-+		    - (plt_address + plt_offset + 8));
-+
-+  uint32_t plt_insn0 = plt_entry[0] | (offset >> 28);
-+  elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
-+  uint32_t plt_insn1 = plt_entry[1] | ((offset >> 20) & 0xff);
-+  elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1);
-+  uint32_t plt_insn2 = plt_entry[2] | ((offset >> 12) & 0xff);
-+  elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
-+  uint32_t plt_insn3 = plt_entry[3] | (offset & 0xfff);
-+  elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3);
-+}
-+
- // Write out the PLT.  This uses the hand-coded instructions above,
- // and adjusts them as needed.  This is all specified by the arm ELF
- // Processor Supplement.
-diff --git a/gold/options.h b/gold/options.h
-index ffc44e6..8b5159f 100644
---- a/gold/options.h
-+++ b/gold/options.h
-@@ -834,6 +834,10 @@ class General_options
- 		    "veneer"),
- 		 NULL);
- 
-+  DEFINE_bool(long_plt, options::TWO_DASHES, '\0', false,
-+	      N_("(ARM only) Generate long PLT entries"),
-+	      N_("(ARM only) Do not generate long PLT entries"));
-+
-   DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
- 	      N_("Ignored"), NULL);
-