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] 2017-08-28 James Clarke <jrtc27 at jrtc27 dot com>


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

commit 972d8a18db78974f59e1a6b1dc02f7e5b7d226d2
Author: Han Shen <shenhan@google.com>
Date:   Mon Aug 28 16:36:45 2017 -0700

    2017-08-28  James Clarke <jrtc27@jrtc27.com>
    
    gold/ChangeLog:
    	PR gold/21868
    	* aarch64.cc (AArch64_relobj::try_fix_erratum_843419_optimized):
    	Add extra view offset argument to function.
    	(AArch64_relobj::fix_errata_and_relocate_erratum_stubs): Add
    	extra view offset set to the output offset when the view has
    	is_input_output_view set, since it has not already been
    	included. Pass this to try_fix_erratum_843419_optimized.

Diff:
---
 gold/aarch64.cc | 46 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 2194a21..a72e2c3 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -1864,7 +1864,7 @@ class AArch64_relobj : public Sized_relobj_file<size, big_endian>
   // applied.
   bool
   try_fix_erratum_843419_optimized(
-      The_erratum_stub*,
+      The_erratum_stub*, AArch64_address,
       typename Sized_relobj_file<size, big_endian>::View_size&);
 
   // Whether a section needs to be scanned for relocation stubs.
@@ -1980,6 +1980,7 @@ AArch64_relobj<size, big_endian>::fix_errata_and_relocate_erratum_stubs(
 {
   typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
   unsigned int shnum = this->shnum();
+  const Relobj::Output_sections& out_sections(this->output_sections());
   for (unsigned int i = 1; i < shnum; ++i)
     {
       The_stub_table* stub_table = this->stub_table(i);
@@ -1988,33 +1989,48 @@ AArch64_relobj<size, big_endian>::fix_errata_and_relocate_erratum_stubs(
       std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter>
 	ipair(stub_table->find_erratum_stubs_for_input_section(this, i));
       Erratum_stub_set_iter p = ipair.first, end = ipair.second;
+      typename Sized_relobj_file<size, big_endian>::View_size&
+	pview((*pviews)[i]);
+      AArch64_address view_offset = 0;
+      if (pview.is_input_output_view)
+	{
+	  // In this case, write_sections has not added the output offset to
+	  // the view's address, so we must do so. Currently this only happens
+	  // for a relaxed section.
+	  unsigned int index = this->adjust_shndx(i);
+	  const Output_relaxed_input_section* poris =
+	      out_sections[index]->find_relaxed_input_section(this, index);
+	  gold_assert(poris != NULL);
+	  view_offset = poris->address() - pview.address;
+	}
+
       while (p != end)
 	{
 	  The_erratum_stub* stub = *p;
-	  typename Sized_relobj_file<size, big_endian>::View_size&
-	    pview((*pviews)[i]);
 
 	  // Double check data before fix.
-	  gold_assert(pview.address + stub->sh_offset()
+	  gold_assert(pview.address + view_offset + stub->sh_offset()
 		      == stub->erratum_address());
 
 	  // Update previously recorded erratum insn with relocated
 	  // version.
 	  Insntype* ip =
-	    reinterpret_cast<Insntype*>(pview.view + stub->sh_offset());
+	    reinterpret_cast<Insntype*>(
+	      pview.view + view_offset + stub->sh_offset());
 	  Insntype insn_to_fix = ip[0];
 	  stub->update_erratum_insn(insn_to_fix);
 
 	  // First try to see if erratum is 843419 and if it can be fixed
 	  // without using branch-to-stub.
-	  if (!try_fix_erratum_843419_optimized(stub, pview))
+	  if (!try_fix_erratum_843419_optimized(stub, view_offset, pview))
 	    {
 	      // Replace the erratum insn with a branch-to-stub.
 	      AArch64_address stub_address =
 		stub_table->erratum_stub_address(stub);
 	      unsigned int b_offset = stub_address - stub->erratum_address();
 	      AArch64_relocate_functions<size, big_endian>::construct_b(
-		pview.view + stub->sh_offset(), b_offset & 0xfffffff);
+		pview.view + view_offset + stub->sh_offset(),
+		b_offset & 0xfffffff);
 	    }
 
           // Erratum fix is done (or skipped), continue to relocate erratum
@@ -2024,7 +2040,8 @@ AArch64_relobj<size, big_endian>::fix_errata_and_relocate_erratum_stubs(
           // erratum stub, ignoring the fact the erratum could never be
           // executed.
           stub_table->relocate_erratum_stub(
-              stub, pview.view + (stub_table->address() - pview.address));
+	    stub,
+	    pview.view + view_offset + (stub_table->address() - pview.address));
 
           // Next erratum stub.
 	  ++p;
@@ -2042,7 +2059,7 @@ AArch64_relobj<size, big_endian>::fix_errata_and_relocate_erratum_stubs(
 template<int size, bool big_endian>
 bool
 AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
-    The_erratum_stub* stub,
+    The_erratum_stub* stub, AArch64_address view_offset,
     typename Sized_relobj_file<size, big_endian>::View_size& pview)
 {
   if (stub->type() != ST_E_843419)
@@ -2052,9 +2069,11 @@ AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
   typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
   E843419_stub<size, big_endian>* e843419_stub =
     reinterpret_cast<E843419_stub<size, big_endian>*>(stub);
-  AArch64_address pc = pview.address + e843419_stub->adrp_sh_offset();
+  AArch64_address pc =
+    pview.address + view_offset + e843419_stub->adrp_sh_offset();
   unsigned int adrp_offset = e843419_stub->adrp_sh_offset ();
-  Insntype* adrp_view = reinterpret_cast<Insntype*>(pview.view + adrp_offset);
+  Insntype* adrp_view =
+    reinterpret_cast<Insntype*>(pview.view + view_offset + adrp_offset);
   Insntype adrp_insn = adrp_view[0];
 
   // If the instruction at adrp_sh_offset is "mrs R, tpidr_el0", it may come
@@ -2070,8 +2089,9 @@ AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
   // return true.
   if (!Insn_utilities::is_adrp(adrp_insn) && adrp_offset)
     {
-      Insntype* prev_view
-	= reinterpret_cast<Insntype*>(pview.view + adrp_offset - 4);
+      Insntype* prev_view =
+	reinterpret_cast<Insntype*>(
+	  pview.view + view_offset + adrp_offset - 4);
       Insntype prev_insn = prev_view[0];
 
       if (Insn_utilities::is_mrs_tpidr_el0(prev_insn))


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