Binutils: Check if AR works with --plugin and rc
[binutils-gdb.git] / gold / powerpc.cc
index fcbe71fbd309009a5c6d147b4b53d1075d8cc1db..e2966ef096b0043cd40dc2f38f41f0f798abcdb7 100644 (file)
@@ -1,6 +1,6 @@
 // powerpc.cc -- powerpc target support for gold.
 
-// Copyright (C) 2008-2020 Free Software Foundation, Inc.
+// Copyright (C) 2008-2021 Free Software Foundation, Inc.
 // Written by David S. Miller <davem@davemloft.net>
 //        and David Edelsohn <edelsohn@gnu.org>
 
@@ -649,8 +649,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
       stub_tables_(), branch_lookup_table_(), branch_info_(), tocsave_loc_(),
       power10_relocs_(false), plt_thread_safe_(false), plt_localentry0_(false),
       plt_localentry0_init_(false), has_localentry0_(false),
-      has_tls_get_addr_opt_(false),
-      tprel_opt_(parameters->options().tls_optimize()),
+      has_tls_get_addr_opt_(false), no_tprel_opt_(false),
       relax_failed_(false), relax_fail_count_(0),
       stub_group_size_(0), savres_section_(0),
       tls_get_addr_(NULL), tls_get_addr_opt_(NULL),
@@ -1154,11 +1153,11 @@ class Target_powerpc : public Sized_target<size, big_endian>
 
   bool
   tprel_opt() const
-  { return this->tprel_opt_; }
+  { return !this->no_tprel_opt_ && parameters->options().tls_optimize(); }
 
   void
-  set_tprel_opt(bool val)
-  { this->tprel_opt_ = val; }
+  set_no_tprel_opt()
+  { this->no_tprel_opt_ = true; }
 
   // Remember any symbols seen with non-zero localentry, even those
   // not providing a definition
@@ -1717,7 +1716,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
   bool plt_localentry0_init_;
   bool has_localentry0_;
   bool has_tls_get_addr_opt_;
-  bool tprel_opt_;
+  bool no_tprel_opt_;
 
   bool relax_failed_;
   int relax_fail_count_;
@@ -3537,7 +3536,7 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
       from += (this->object_->output_section(this->shndx_)->address()
               + this->offset_);
       Address to;
-      unsigned int other;
+      unsigned int other = 0;
       if (gsym != NULL)
        {
          switch (gsym->source())
@@ -3565,7 +3564,8 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
          to = symtab->compute_final_value<size>(gsym, &status);
          if (status != Symbol_table::CFVS_OK)
            return true;
-         other = gsym->nonvis() >> 3;
+         if (size == 64)
+           other = gsym->nonvis() >> 3;
        }
       else
        {
@@ -3582,7 +3582,8 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
              || !symval.has_output_value())
            return true;
          to = symval.value(this->object_, 0);
-         other = this->object_->st_other(this->r_sym_) >> 5;
+         if (size == 64)
+           other = this->object_->st_other(this->r_sym_) >> 5;
        }
       if (!(size == 32 && this->r_type_ == elfcpp::R_PPC_PLTREL24))
        to += this->addend_;
@@ -5304,7 +5305,7 @@ Stub_table<size, big_endian>::add_long_branch_entry(
        this->need_resize_ = true;
       p.first->second.toc_ = true;
     }
-  if (p.first->second.other_ == 0)
+  if (size == 64 && p.first->second.other_ == 0)
     p.first->second.other_ = other;
   gold_assert(save_res == p.first->second.save_res_);
   if (p.second || (this->resizing_ && !p.first->second.iter_))
@@ -8471,7 +8472,7 @@ Target_powerpc<size, big_endian>::Scan::local(
              uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
              if ((insn & ((0x3fu << 26) | 0x1f << 16))
                  != ((15u << 26) | ((size == 32 ? 2 : 13) << 16)))
-               target->set_tprel_opt(false);
+               target->set_no_tprel_opt();
            }
        }
       break;
@@ -8486,7 +8487,7 @@ Target_powerpc<size, big_endian>::Scan::local(
        break;
       // Fall through.
     case elfcpp::R_POWERPC_TPREL16_HI:
-      target->set_tprel_opt(false);
+      target->set_no_tprel_opt();
       break;
     default:
       break;
@@ -9268,7 +9269,7 @@ Target_powerpc<size, big_endian>::Scan::global(
              uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
              if ((insn & ((0x3fu << 26) | 0x1f << 16))
                  != ((15u << 26) | ((size == 32 ? 2 : 13) << 16)))
-               target->set_tprel_opt(false);
+               target->set_no_tprel_opt();
            }
        }
       break;
@@ -9283,7 +9284,7 @@ Target_powerpc<size, big_endian>::Scan::global(
        break;
       // Fall through.
     case elfcpp::R_POWERPC_TPREL16_HI:
-      target->set_tprel_opt(false);
+      target->set_no_tprel_opt();
       break;
     default:
       break;