gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / powerpc.cc
index 9c2a906bcde77647b446b819d4bd9cefaae88372..318c41744b5c52f73a4386246e1812c2851255c1 100644 (file)
@@ -647,7 +647,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
       glink_(NULL), rela_dyn_(NULL), copy_relocs_(),
       tlsld_got_offset_(-1U),
       stub_tables_(), branch_lookup_table_(), branch_info_(), tocsave_loc_(),
-      powerxx_stubs_(false), plt_thread_safe_(false), plt_localentry0_(false),
+      power10_stubs_(false), plt_thread_safe_(false), plt_localentry0_(false),
       plt_localentry0_init_(false), has_localentry0_(false),
       has_tls_get_addr_opt_(false),
       relax_failed_(false), relax_fail_count_(0),
@@ -1079,13 +1079,13 @@ class Target_powerpc : public Sized_target<size, big_endian>
   }
 
   bool
-  powerxx_stubs() const
-  { return this->powerxx_stubs_; }
+  power10_stubs() const
+  { return this->power10_stubs_; }
 
   void
-  set_powerxx_stubs()
+  set_power10_stubs()
   {
-    this->powerxx_stubs_ = true;
+    this->power10_stubs_ = true;
   }
 
   bool
@@ -1204,7 +1204,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
 
   // Merge object attributes from input object with those in the output.
   void
-  merge_object_attributes(const char*, const Attributes_section_data*);
+  merge_object_attributes(const Object*, const Attributes_section_data*);
 
  private:
 
@@ -1687,7 +1687,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
   Branches branch_info_;
   Tocsave_loc tocsave_loc_;
 
-  bool powerxx_stubs_;
+  bool power10_stubs_;
   bool plt_thread_safe_;
   bool plt_localentry0_;
   bool plt_localentry0_init_;
@@ -5073,7 +5073,7 @@ Stub_table<size, big_endian>::add_plt_call_entry(
       if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
        {
          if (!p.second && !p.first->second.notoc_
-             && !this->targ_->powerxx_stubs())
+             && !this->targ_->power10_stubs())
            this->need_resize_ = true;
          p.first->second.notoc_ = 1;
        }
@@ -5124,7 +5124,7 @@ Stub_table<size, big_endian>::add_plt_call_entry(
       if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
        {
          if (!p.second && !p.first->second.notoc_
-             && !this->targ_->powerxx_stubs())
+             && !this->targ_->power10_stubs())
            this->need_resize_ = true;
          p.first->second.notoc_ = 1;
        }
@@ -5330,7 +5330,7 @@ Stub_table<size, big_endian>::add_eh_frame(Layout* layout)
           && cs->second.r2save_
           && !cs->second.localentry0_)
          || (cs->second.notoc_
-             && !this->targ_->powerxx_stubs()))
+             && !this->targ_->power10_stubs()))
        calls.push_back(cs);
   if (calls.size() > 1)
     std::stable_sort(calls.begin(), calls.end(),
@@ -5339,7 +5339,7 @@ Stub_table<size, big_endian>::add_eh_frame(Layout* layout)
   typedef typename Branch_stub_entries::const_iterator branch_iter;
   std::vector<branch_iter> branches;
   if (!this->long_branch_stubs_.empty()
-      && !this->targ_->powerxx_stubs())
+      && !this->targ_->power10_stubs())
     for (branch_iter bs = this->long_branch_stubs_.begin();
         bs != this->long_branch_stubs_.end();
         ++bs)
@@ -5776,7 +5776,7 @@ Stub_table<size, big_endian>::build_tls_opt_tail(
 
 template<bool big_endian>
 static unsigned char*
-build_powerxx_offset(unsigned char* p, uint64_t off, uint64_t odd, bool load)
+build_power10_offset(unsigned char* p, uint64_t off, uint64_t odd, bool load)
 {
   uint64_t insn;
   if (off - odd + (1ULL << 33) < 1ULL << 34)
@@ -5964,7 +5964,7 @@ Stub_table<size, big_endian>::plt_call_size(
   if (p->second.r2save_)
     bytes += 4;
 
-  if (this->targ_->powerxx_stubs())
+  if (this->targ_->power10_stubs())
     {
       uint64_t from = this->stub_address() + p->second.off_ + bytes;
       if (bytes > 8 * 4)
@@ -6045,7 +6045,7 @@ Stub_table<size, big_endian>::branch_stub_size(
   uint64_t off = p->first.dest_ - loc;
   if (p->second.notoc_)
     {
-      if (this->targ_->powerxx_stubs())
+      if (this->targ_->power10_stubs())
        {
          Address odd = loc & 4;
          if (off + (1 << 25) < 2 << 25)
@@ -6080,7 +6080,7 @@ Stub_table<size, big_endian>::branch_stub_size(
 
   if (off + (1 << 25) < 2 << 25)
     return 4;
-  if (!this->targ_->powerxx_stubs())
+  if (!this->targ_->power10_stubs())
     *need_lt = true;
   return 16;
 }
@@ -6116,7 +6116,7 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
   unsigned char* p;
 
   if (size == 64
-      && this->targ_->powerxx_stubs())
+      && this->targ_->power10_stubs())
     {
       if (!this->plt_call_stubs_.empty())
        {
@@ -6138,7 +6138,7 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
              Address plt_addr = pltoff + plt->address();
              Address from = this->stub_address() + (p - oview);
              Address delta = plt_addr - from;
-             p = build_powerxx_offset<big_endian>(p, delta, from & 4, true);
+             p = build_power10_offset<big_endian>(p, delta, from & 4, true);
              write_insn<big_endian>(p, mtctr_12);
              p += 4;
              if (!this->build_tls_opt_tail(p, cs))
@@ -6161,7 +6161,7 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
          if (bs->second.notoc_ || delta + (1 << 25) >= 2 << 25)
            {
              unsigned char* startp = p;
-             p = build_powerxx_offset<big_endian>(p, delta, loc & 4, false);
+             p = build_power10_offset<big_endian>(p, delta, loc & 4, false);
              delta -= p - startp;
            }
          if (delta + (1 << 25) < 2 << 25)
@@ -8181,7 +8181,7 @@ Target_powerpc<size, big_endian>::Scan::local(
     case elfcpp::R_PPC64_GOT_TLSLD34:
     case elfcpp::R_PPC64_GOT_DTPREL34:
     case elfcpp::R_PPC64_GOT_TPREL34:
-      target->set_powerxx_stubs();
+      target->set_power10_stubs();
       break;
     default:
       break;
@@ -8939,7 +8939,7 @@ Target_powerpc<size, big_endian>::Scan::global(
     case elfcpp::R_PPC64_GOT_TLSLD34:
     case elfcpp::R_PPC64_GOT_DTPREL34:
     case elfcpp::R_PPC64_GOT_TPREL34:
-      target->set_powerxx_stubs();
+      target->set_power10_stubs();
       break;
     default:
       break;
@@ -9056,7 +9056,7 @@ Target_powerpc<size, big_endian>::do_gc_mark_symbol(
     Symbol_table* symtab,
     Symbol* sym) const
 {
-  if (size == 64)
+  if (size == 64 && sym->object()->pluginobj() == NULL)
     {
       Powerpc_relobj<size, big_endian>* ppc_object
        = static_cast<Powerpc_relobj<size, big_endian>*>(sym->object());
@@ -9481,7 +9481,7 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
       Powerpc_relobj<size, big_endian>* ppc_relobj
        = static_cast<Powerpc_relobj<size, big_endian>*>(*p);
       if (ppc_relobj->attributes_section_data())
-       this->merge_object_attributes(ppc_relobj->name().c_str(),
+       this->merge_object_attributes(ppc_relobj,
                                      ppc_relobj->attributes_section_data());
     }
   for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
@@ -9491,7 +9491,7 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
       Powerpc_dynobj<size, big_endian>* ppc_dynobj
        = static_cast<Powerpc_dynobj<size, big_endian>*>(*p);
       if (ppc_dynobj->attributes_section_data())
-       this->merge_object_attributes(ppc_dynobj->name().c_str(),
+       this->merge_object_attributes(ppc_dynobj,
                                      ppc_dynobj->attributes_section_data());
     }
 
@@ -9514,7 +9514,7 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
 template<int size, bool big_endian>
 void
 Target_powerpc<size, big_endian>::merge_object_attributes(
-    const char* name,
+    const Object* obj,
     const Attributes_section_data* pasd)
 {
   // Return if there is no attributes section data.
@@ -9530,12 +9530,14 @@ Target_powerpc<size, big_endian>::merge_object_attributes(
   Object_attribute* out_attr
     = this->attributes_section_data_->known_attributes(vendor);
 
+  const char* name = obj->name().c_str();
   const char* err;
   const char* first;
   const char* second;
   int tag = elfcpp::Tag_GNU_Power_ABI_FP;
   int in_fp = in_attr[tag].int_value() & 0xf;
   int out_fp = out_attr[tag].int_value() & 0xf;
+  bool warn_only = obj->is_dynamic();
   if (in_fp != out_fp)
     {
       err = NULL;
@@ -9543,10 +9545,13 @@ Target_powerpc<size, big_endian>::merge_object_attributes(
        ;
       else if ((out_fp & 3) == 0)
        {
-         out_fp |= in_fp & 3;
-         out_attr[tag].set_int_value(out_fp);
-         out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
-         this->last_fp_ = name;
+         if (!warn_only)
+           {
+             out_fp |= in_fp & 3;
+             out_attr[tag].set_int_value(out_fp);
+             out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
+             this->last_fp_ = name;
+           }
        }
       else if ((out_fp & 3) != 2 && (in_fp & 3) == 2)
        {
@@ -9579,10 +9584,13 @@ Target_powerpc<size, big_endian>::merge_object_attributes(
        ;
       else if ((out_fp & 0xc) == 0)
        {
-         out_fp |= in_fp & 0xc;
-         out_attr[tag].set_int_value(out_fp);
-         out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
-         this->last_ld_ = name;
+         if (!warn_only)
+           {
+             out_fp |= in_fp & 0xc;
+             out_attr[tag].set_int_value(out_fp);
+             out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
+             this->last_ld_ = name;
+           }
        }
       else if ((out_fp & 0xc) != 2 * 4 && (in_fp & 0xc) == 2 * 4)
        {
@@ -9612,10 +9620,16 @@ Target_powerpc<size, big_endian>::merge_object_attributes(
       if (err)
        {
          if (parameters->options().warn_mismatch())
-           gold_error(_(err), first, second);
+           {
+             if (warn_only)
+               gold_warning(_(err), first, second);
+             else
+               gold_error(_(err), first, second);
+           }
          // Arrange for this attribute to be deleted.  It's better to
          // say "don't know" about a file than to wrongly claim compliance.
-         out_attr[tag].set_type(0);
+         if (!warn_only)
+           out_attr[tag].set_type(0);
        }
     }
 
This page took 0.028739 seconds and 4 git commands to generate.