This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix internal error in fix_errata on aarch64.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fd6798fa2d6f0374d45449c4212869da93623b1e

commit fd6798fa2d6f0374d45449c4212869da93623b1e
Author: Peter Smith <peter.smith@linaro.org>
Date:   Thu Nov 30 15:07:26 2017 -0800

    Fix internal error in fix_errata on aarch64.
    
    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.

Diff:
---
 gold/ChangeLog  |  7 +++++++
 gold/aarch64.cc | 25 +++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index 1245da5..43a3d70 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,4 +1,11 @@
 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>
 
 	PR gold/20765
diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 04da01d..5e702db 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]