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] [GOLD] PowerPC --no-tls-optimize


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

commit aacb3b6dfc7a9162a049dada22f1079809188f02
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jul 31 19:53:49 2017 +0930

    [GOLD] PowerPC --no-tls-optimize
    
    This adds a --no-tls-optimize option for people who want to keep
    __tls_get_addr calls in an executable rather than optimizing such code
    sequences to IE/LE.
    
    Also tidy some formatting errors, rename a variable to better reflect
    its use, and tweak two functions that create pairs of GOT entries to
    first check whether the GOT entry already exists before potentially
    inserting the header via reserve(2).  Without the check it is possible
    to waste one GOT entry.
    
    	* options.h (no_tls_optimize): New powerpc option.
    	* powerpc.cc (Target_powerpc::abiversion, set_abiversion): Formatting.
    	(Target_powerpc::stk_toc): Formatting, fix comment.
    	(Target_powerpc::Track_tls::tls_get_addr_state): Rename from
    	tls_get_addr.
    	(Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie):
    	Return TLSOPT_NONE when !tls_optimize.
    	(Target_powerpc::add_global_pair_with_rel): Check
    	for existing reloc before reserving.
    	(Target_powerpc::add_local_tls_pair): Likewise.

Diff:
---
 gold/ChangeLog  | 13 +++++++++++++
 gold/options.h  |  4 ++++
 gold/powerpc.cc | 40 +++++++++++++++++++++++++---------------
 3 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index e7567e6..869a01d 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,18 @@
 2017-07-31  Alan Modra  <amodra@gmail.com>
 
+	* options.h (no_tls_optimize): New powerpc option.
+	* powerpc.cc (Target_powerpc::abiversion, set_abiversion): Formatting.
+	(Target_powerpc::stk_toc): Formatting, fix comment.
+	(Target_powerpc::Track_tls::tls_get_addr_state): Rename from
+	tls_get_addr.
+	(Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie):
+	Return TLSOPT_NONE when !tls_optimize.
+	(Target_powerpc::add_global_pair_with_rel): Check
+	for existing reloc before reserving.
+	(Target_powerpc::add_local_tls_pair): Likewise.
+
+2017-07-31  Alan Modra  <amodra@gmail.com>
+
 	* powerpc.cc (Target_powerpc::scan_relocs): Warn on --plt-localentry
 	without ld.so checks.
 
diff --git a/gold/options.h b/gold/options.h
index c7c032b..7be15a5 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1290,6 +1290,10 @@ class General_options
   DEFINE_uint(thread_count_final, options::TWO_DASHES, '\0', 0,
 	      N_("Number of threads to use in final pass"), N_("COUNT"));
 
+  DEFINE_bool(tls_optimize, options::TWO_DASHES, '\0', true,
+	      N_("(PowerPC/64 only) Optimize GD/LD/IE code to IE/LE"),
+	      N_("(PowerPC/64 only) Don'\''t try to optimize TLS accesses"));
+
   DEFINE_bool(toc_optimize, options::TWO_DASHES, '\0', true,
 	      N_("(PowerPC64 only) Optimize TOC code sequences"),
 	      N_("(PowerPC64 only) Don't optimize TOC code sequences"));
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 14e56d8..9a200ab 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -1052,11 +1052,11 @@ class Target_powerpc : public Sized_target<size, big_endian>
   }
 
   int
-  abiversion () const
+  abiversion() const
   { return this->processor_specific_flags() & elfcpp::EF_PPC64_ABI; }
 
   void
-  set_abiversion (int ver)
+  set_abiversion(int ver)
   {
     elfcpp::Elf_Word flags = this->processor_specific_flags();
     flags &= ~elfcpp::EF_PPC64_ABI;
@@ -1064,9 +1064,9 @@ class Target_powerpc : public Sized_target<size, big_endian>
     this->set_processor_specific_flags(flags);
   }
 
-  // Offset to save stack slot
+  // Offset to toc save stack slot
   int
-  stk_toc () const
+  stk_toc() const
   { return this->abiversion() < 2 ? 40 : 24; }
 
  private:
@@ -1083,13 +1083,13 @@ class Target_powerpc : public Sized_target<size, big_endian>
     };
 
     Track_tls()
-      : tls_get_addr_(NOT_EXPECTED),
+      : tls_get_addr_state_(NOT_EXPECTED),
 	relinfo_(NULL), relnum_(0), r_offset_(0)
     { }
 
     ~Track_tls()
     {
-      if (this->tls_get_addr_ != NOT_EXPECTED)
+      if (this->tls_get_addr_state_ != NOT_EXPECTED)
 	this->missing();
     }
 
@@ -1107,7 +1107,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
 	size_t relnum,
 	Address r_offset)
     {
-      this->tls_get_addr_ = EXPECTED;
+      this->tls_get_addr_state_ = EXPECTED;
       this->relinfo_ = relinfo;
       this->relnum_ = relnum;
       this->r_offset_ = r_offset;
@@ -1115,11 +1115,11 @@ class Target_powerpc : public Sized_target<size, big_endian>
 
     void
     expect_tls_get_addr_call()
-    { this->tls_get_addr_ = EXPECTED; }
+    { this->tls_get_addr_state_ = EXPECTED; }
 
     void
     skip_next_tls_get_addr_call()
-    {this->tls_get_addr_ = SKIP; }
+    {this->tls_get_addr_state_ = SKIP; }
 
     Tls_get_addr
     maybe_skip_tls_get_addr_call(unsigned int r_type, const Symbol* gsym)
@@ -1128,8 +1128,8 @@ class Target_powerpc : public Sized_target<size, big_endian>
 			   || r_type == elfcpp::R_PPC_PLTREL24)
 			  && gsym != NULL
 			  && strcmp(gsym->name(), "__tls_get_addr") == 0);
-      Tls_get_addr last_tls = this->tls_get_addr_;
-      this->tls_get_addr_ = NOT_EXPECTED;
+      Tls_get_addr last_tls = this->tls_get_addr_state_;
+      this->tls_get_addr_state_ = NOT_EXPECTED;
       if (is_tls_call && last_tls != EXPECTED)
 	return last_tls;
       else if (!is_tls_call && last_tls != NOT_EXPECTED)
@@ -1152,7 +1152,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
     // allowing ld to safely optimize away the call.  We check that
     // every call to __tls_get_addr has a marker relocation, and that
     // every marker relocation is on a call to __tls_get_addr.
-    Tls_get_addr tls_get_addr_;
+    Tls_get_addr tls_get_addr_state_;
     // Info about the last reloc for error message.
     const Relocate_info<size, big_endian>* relinfo_;
     size_t relnum_;
@@ -1323,7 +1323,8 @@ class Target_powerpc : public Sized_target<size, big_endian>
   {
     // If we are generating a shared library, then we can't do anything
     // in the linker.
-    if (parameters->options().shared())
+    if (parameters->options().shared()
+	|| !parameters->options().tls_optimize())
       return tls::TLSOPT_NONE;
 
     if (!is_final)
@@ -1334,7 +1335,8 @@ class Target_powerpc : public Sized_target<size, big_endian>
   tls::Tls_optimization
   optimize_tls_ld()
   {
-    if (parameters->options().shared())
+    if (parameters->options().shared()
+	|| !parameters->options().tls_optimize())
       return tls::TLSOPT_NONE;
 
     return tls::TLSOPT_TO_LE;
@@ -1343,7 +1345,9 @@ class Target_powerpc : public Sized_target<size, big_endian>
   tls::Tls_optimization
   optimize_tls_ie(bool is_final)
   {
-    if (!is_final || parameters->options().shared())
+    if (!is_final
+	|| parameters->options().shared()
+	|| !parameters->options().tls_optimize())
       return tls::TLSOPT_NONE;
 
     return tls::TLSOPT_TO_LE;
@@ -2525,6 +2529,9 @@ public:
 			   Output_data_reloc_generic* rel_dyn,
 			   unsigned int r_type_1, unsigned int r_type_2)
   {
+    if (gsym->has_got_offset(got_type))
+      return;
+
     this->reserve_ent(2);
     Output_data_got<size, big_endian>::
       add_global_pair_with_rel(gsym, got_type, rel_dyn, r_type_1, r_type_2);
@@ -2556,6 +2563,9 @@ public:
 		     Output_data_reloc_generic* rel_dyn,
 		     unsigned int r_type)
   {
+    if (object->local_has_got_offset(sym_index, got_type))
+      return;
+
     this->reserve_ent(2);
     Output_data_got<size, big_endian>::
       add_local_tls_pair(object, sym_index, got_type, rel_dyn, r_type);


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