]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix internal error in fix_errata on aarch64.
authorPeter Smith <peter.smith@linaro.org>
Thu, 30 Nov 2017 23:07:26 +0000 (15:07 -0800)
committerCary Coutant <ccoutant@gmail.com>
Thu, 30 Nov 2017 23:08:21 +0000 (15:08 -0800)
The addresses of erratum stubs can be changed by relaxation passes, and
need to be updated.

gold/
PR gold/20765
* aarch64.cc (Aarch64_relobj::update_erratum_address): New method.
(AArch64_relobj::scan_errata): Update addresses in stub table after
relaxation pass.

gold/ChangeLog
gold/aarch64.cc

index 1245da5c53b4732502c4866ecc46b88a8507a6d4..43a3d70e9f6845b6c3dc0a84dce8a6df9f0c7ab2 100644 (file)
@@ -1,3 +1,10 @@
+2017-11-30  Peter Smith  <peter.smith@linaro.org>
+
+       PR gold/20765
+       * aarch64.cc (Aarch64_relobj::update_erratum_address): New method.
+       (AArch64_relobj::scan_errata): Update addresses in stub table after
+       relaxation pass.
+
 2017-11-30  Peter Smith  <peter.smith@linaro.org>
            Cary Coutant  <ccoutant@gmail.com>
 
index 04da01d51fa7626c823ca864cc09a450ac87804a..5e702dbfd7710ef614da536ef35fe3c58b6cbba0 100644 (file)
@@ -1031,6 +1031,18 @@ public:
   set_erratum_address(AArch64_address addr)
   { this->erratum_address_ = addr; }
 
+  // Later relaxation passes of may alter the recorded erratum and destination
+  // address. Given an up to date output section address of shidx_ in
+  // relobj_ we can derive the erratum_address and destination address.
+  void
+  update_erratum_address(AArch64_address output_section_addr)
+  {
+    const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
+    AArch64_address updated_addr = output_section_addr + this->sh_offset_;
+    this->set_erratum_address(updated_addr);
+    this->set_destination_address(updated_addr + BPI);
+  }
+
   // Comparator used to group Erratum_stubs in a set by (obj, shndx,
   // sh_offset). We do not include 'type' in the calculation, because there is
   // at most one stub type at (obj, shndx, sh_offset).
@@ -2304,6 +2316,19 @@ AArch64_relobj<size, big_endian>::scan_errata(
       output_address = poris->address();
     }
 
+  // Update the addresses in previously generated erratum stubs. Unlike when
+  // we scan relocations for stubs, if section addresses have changed due to
+  // other relaxations we are unlikely to scan the same erratum instances
+  // again.
+  The_stub_table* stub_table = this->stub_table(shndx);
+  if (stub_table)
+    {
+      std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter>
+         ipair(stub_table->find_erratum_stubs_for_input_section(this, shndx));
+      for (Erratum_stub_set_iter p = ipair.first;  p != ipair.second; ++p)
+          (*p)->update_erratum_address(output_address);
+    }
+
   section_size_type input_view_size = 0;
   const unsigned char* input_view =
     this->section_contents(shndx, &input_view_size, false);