public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][gold] Mips: Fix emitting .reginfo section.
@ 2016-05-06 15:53 Vladimir Radosavljevic
  2016-05-19 22:51 ` Cary Coutant
  0 siblings, 1 reply; 3+ messages in thread
From: Vladimir Radosavljevic @ 2016-05-06 15:53 UTC (permalink / raw)
  To: binutils; +Cc: ccoutant, Petar Jovanovic

[-- Attachment #1: Type: text/plain, Size: 1128 bytes --]

In Target_mips::do_should_include_section method we exclude all input .reginfo sections,
so in Target_mips::do_make_output_section we won't create object of class Mips_output_section_reginfo,
and we will never emit .reginfo section. This patch fixes that.

Regards,
Vladimir

ChangeLog -

	* mips.cc (Mips_relobj::Mips_relobj): Initialize
	has_reginfo_section_.
	(Mips_relobj::has_reginfo_section_): New data member.
	(Mips_relobj::has_reginfo_section): New method.
	(class Mips_output_section_reginfo): Change base class to
	Output_section_data, and set masks of the output .reginfo section
	in constructor.
	(Mips_output_section_reginfo::as_mips_output_section_reginfo):
	Remove.
	(Mips_output_section_reginfo::set_masks): Likewise.
	(Mips_output_section_reginfo::set_final_data_size): Likewise.
	(Mips_output_section_reginfo::do_print_to_mapfile): New method.
	(Target_mips::do_make_output_section): Remove.
	(Mips_relobj::do_read_symbols): Set has_reginfo_section_ to true
	if the object contains a .reginfo section.
	(Target_mips::do_finalize_sections): Create a .reginfo output
	section if needed.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: reginfo.patch --]
[-- Type: text/x-patch; name="reginfo.patch", Size: 9494 bytes --]

diff --git a/gold/mips.cc b/gold/mips.cc
index ffaad45..fed258e 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -1530,10 +1530,11 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian>
       processor_specific_flags_(0), local_symbol_is_mips16_(),
       local_symbol_is_micromips_(), mips16_stub_sections_(),
       local_non_16bit_calls_(), local_16bit_calls_(), local_mips16_fn_stubs_(),
-      local_mips16_call_stubs_(), gp_(0), got_info_(NULL),
-      section_is_mips16_fn_stub_(), section_is_mips16_call_stub_(),
-      section_is_mips16_call_fp_stub_(), pdr_shndx_(-1U), gprmask_(0),
-      cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0)
+      local_mips16_call_stubs_(), gp_(0), has_reginfo_section_(false),
+      got_info_(NULL), section_is_mips16_fn_stub_(),
+      section_is_mips16_call_stub_(), section_is_mips16_call_fp_stub_(),
+      pdr_shndx_(-1U), gprmask_(0), cprmask1_(0), cprmask2_(0), cprmask3_(0),
+      cprmask4_(0)
   {
     this->is_pic_ = (ehdr.get_e_flags() & elfcpp::EF_MIPS_PIC) != 0;
     this->is_n32_ = elfcpp::abi_n32(ehdr.get_e_flags());
@@ -1769,6 +1770,11 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian>
   void
   discard_mips16_stub_sections(Symbol_table* symtab);
 
+  // Return whether there is a .reginfo section.
+  bool
+  has_reginfo_section() const
+  { return has_reginfo_section_; }
+
   // Return gprmask from the .reginfo section of this object.
   Valtype
   gprmask() const
@@ -1847,6 +1853,8 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian>
   bool is_pic_ : 1;
   // Whether the object uses N32 ABI.
   bool is_n32_ : 1;
+  // Whether the object contains a .reginfo section.
+  bool has_reginfo_section_ : 1;
   // The Mips_got_info for this object.
   Mips_got_info<size, big_endian>* got_info_;
 
@@ -2695,40 +2703,25 @@ class Mips_output_data_mips_stubs : public Output_section_data
 // This class handles Mips .reginfo output section.
 
 template<int size, bool big_endian>
-class Mips_output_section_reginfo : public Output_section
+class Mips_output_section_reginfo : public Output_section_data
 {
   typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
 
  public:
-  Mips_output_section_reginfo(const char* name, elfcpp::Elf_Word type,
-                              elfcpp::Elf_Xword flags,
-                              Target_mips<size, big_endian>* target)
-    : Output_section(name, type, flags), target_(target), gprmask_(0),
-      cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0)
+  Mips_output_section_reginfo(Target_mips<size, big_endian>* target,
+                              Valtype gprmask, Valtype cprmask1,
+                              Valtype cprmask2, Valtype cprmask3,
+                              Valtype cprmask4)
+    : Output_section_data(24, 4, true), target_(target),
+      gprmask_(gprmask), cprmask1_(cprmask1), cprmask2_(cprmask2),
+      cprmask3_(cprmask3), cprmask4_(cprmask4)
   { }
 
-  // Downcast a base pointer to a Mips_output_section_reginfo pointer.
-  static Mips_output_section_reginfo<size, big_endian>*
-  as_mips_output_section_reginfo(Output_section* os)
-  { return static_cast<Mips_output_section_reginfo<size, big_endian>*>(os); }
-
-  // Set masks of the output .reginfo section.
-  void
-  set_masks(Valtype gprmask, Valtype cprmask1, Valtype cprmask2,
-            Valtype cprmask3, Valtype cprmask4)
-  {
-    this->gprmask_ = gprmask;
-    this->cprmask1_ = cprmask1;
-    this->cprmask2_ = cprmask2;
-    this->cprmask3_ = cprmask3;
-    this->cprmask4_ = cprmask4;
-  }
-
  protected:
-  // Set the final data size.
+  // Write to a map file.
   void
-  set_final_data_size()
-  { this->set_data_size(24); }
+  do_print_to_mapfile(Mapfile* mapfile) const
+  { mapfile->print_output_data(this, _(".reginfo")); }
 
   // Write out reginfo section.
   void
@@ -3527,18 +3520,6 @@ class Target_mips : public Sized_target<size, big_endian>
                      const elfcpp::Ehdr<size, !big_endian>&)
   { gold_unreachable(); }
 
-  // Make an output section.
-  Output_section*
-  do_make_output_section(const char* name, elfcpp::Elf_Word type,
-                         elfcpp::Elf_Xword flags)
-    {
-      if (type == elfcpp::SHT_MIPS_REGINFO)
-        return new Mips_output_section_reginfo<size, big_endian>(name, type,
-                                                                 flags, this);
-      else
-        return new Output_section(name, type, flags);
-    }
-
   // Adjust ELF file header.
   void
   do_adjust_elf_header(unsigned char* view, int len);
@@ -6381,6 +6362,7 @@ Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
 
       if (shdr.get_sh_type() == elfcpp::SHT_MIPS_REGINFO)
         {
+          this->has_reginfo_section_ = true;
           // Read the gp value that was used to create this object.  We need the
           // gp value while processing relocs.  The .reginfo section is not used
           // in the 64-bit MIPS ELF ABI.
@@ -7689,8 +7671,6 @@ Mips_output_section_reginfo<size, big_endian>::do_write(Output_file* of)
   // Write the gp value.
   elfcpp::Swap<size, big_endian>::writeval(view + 20,
                                            this->target_->gp_value());
-
-  of->write_output_view(offset, data_size, view);
 }
 
 // Mips_copy_relocs methods.
@@ -8589,6 +8569,13 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
         }
     }
 
+  Valtype gprmask = 0;
+  Valtype cprmask1 = 0;
+  Valtype cprmask2 = 0;
+  Valtype cprmask3 = 0;
+  Valtype cprmask4 = 0;
+  bool has_reginfo_section = false;
+
   // Merge processor-specific flags.
   for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
        p != input_objects->relobj_end();
@@ -8597,6 +8584,17 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
       Mips_relobj<size, big_endian>* relobj =
         Mips_relobj<size, big_endian>::as_mips_relobj(*p);
 
+      // Merge .reginfo contents of input objects.
+      if (relobj->has_reginfo_section())
+        {
+          has_reginfo_section = true;
+          gprmask |= relobj->gprmask();
+          cprmask1 |= relobj->cprmask1();
+          cprmask2 |= relobj->cprmask2();
+          cprmask3 |= relobj->cprmask3();
+          cprmask4 |= relobj->cprmask4();
+        }
+
       Input_file::Format format = relobj->input_file()->format();
       if (format == Input_file::FORMAT_ELF)
         {
@@ -8643,24 +8641,26 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
       this->merge_processor_specific_flags(dynobj->name(), in_flags, true);
     }
 
-  // Merge .reginfo contents of input objects.
-  Valtype gprmask = 0;
-  Valtype cprmask1 = 0;
-  Valtype cprmask2 = 0;
-  Valtype cprmask3 = 0;
-  Valtype cprmask4 = 0;
-  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
-       p != input_objects->relobj_end();
-       ++p)
+  if (has_reginfo_section && !parameters->options().gc_sections())
     {
-      Mips_relobj<size, big_endian>* relobj =
-        Mips_relobj<size, big_endian>::as_mips_relobj(*p);
+      // Create .reginfo output section.
+      Mips_output_section_reginfo<size, big_endian>* reginfo_section =
+        new Mips_output_section_reginfo<size, big_endian>(this, gprmask,
+                                                          cprmask1, cprmask2,
+                                                          cprmask3, cprmask4);
+
+      Output_section* os =
+        layout->add_output_section_data(".reginfo", elfcpp::SHT_MIPS_REGINFO,
+                                        elfcpp::SHF_ALLOC, reginfo_section,
+                                        ORDER_INVALID, false);
 
-      gprmask |= relobj->gprmask();
-      cprmask1 |= relobj->cprmask1();
-      cprmask2 |= relobj->cprmask2();
-      cprmask3 |= relobj->cprmask3();
-      cprmask4 |= relobj->cprmask4();
+      if (!parameters->options().relocatable() && os != NULL)
+        {
+          Output_segment* reginfo_segment =
+            layout->make_output_segment(elfcpp::PT_MIPS_REGINFO,
+                                        elfcpp::PF_R);
+          reginfo_segment->add_output_section_to_nonload(os, elfcpp::PF_R);
+        }
     }
 
   if (this->plt_ != NULL)
@@ -8731,29 +8731,6 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
   if (!parameters->options().relocatable())
     layout->make_output_segment(elfcpp::PT_NULL, 0);
 
-  for (Layout::Section_list::const_iterator p = layout->section_list().begin();
-       p != layout->section_list().end();
-       ++p)
-    {
-      if ((*p)->type() == elfcpp::SHT_MIPS_REGINFO)
-        {
-          Mips_output_section_reginfo<size, big_endian>* reginfo =
-            Mips_output_section_reginfo<size, big_endian>::
-              as_mips_output_section_reginfo(*p);
-
-          reginfo->set_masks(gprmask, cprmask1, cprmask2, cprmask3, cprmask4);
-
-          if (!parameters->options().relocatable())
-            {
-              Output_segment* reginfo_segment =
-                layout->make_output_segment(elfcpp::PT_MIPS_REGINFO,
-                                            elfcpp::PF_R);
-              reginfo_segment->add_output_section_to_nonload(reginfo,
-                                                             elfcpp::PF_R);
-            }
-        }
-    }
-
   // Fill in some more dynamic tags.
   // TODO(sasa): Add more dynamic tags.
   const Reloc_section* rel_plt = (this->plt_ == NULL

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][gold] Mips: Fix emitting .reginfo section.
  2016-05-06 15:53 [PATCH][gold] Mips: Fix emitting .reginfo section Vladimir Radosavljevic
@ 2016-05-19 22:51 ` Cary Coutant
  2016-05-23 15:57   ` Vladimir Radosavljevic
  0 siblings, 1 reply; 3+ messages in thread
From: Cary Coutant @ 2016-05-19 22:51 UTC (permalink / raw)
  To: Vladimir Radosavljevic; +Cc: binutils, Petar Jovanovic

> In Target_mips::do_should_include_section method we exclude all input .reginfo sections,
> so in Target_mips::do_make_output_section we won't create object of class Mips_output_section_reginfo,
> and we will never emit .reginfo section. This patch fixes that.

+  // Return whether there is a .reginfo section.
+  bool
+  has_reginfo_section() const
+  { return has_reginfo_section_; }

Need "this->".

@@ -7689,8 +7671,6 @@ Mips_output_section_reginfo<size,
big_endian>::do_write(Output_file* of)
   // Write the gp value.
   elfcpp::Swap<size, big_endian>::writeval(view + 20,
                                            this->target_->gp_value());
-
-  of->write_output_view(offset, data_size, view);

Why did you remove the call to write_output_view?

-cary

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH][gold] Mips: Fix emitting .reginfo section.
  2016-05-19 22:51 ` Cary Coutant
@ 2016-05-23 15:57   ` Vladimir Radosavljevic
  0 siblings, 0 replies; 3+ messages in thread
From: Vladimir Radosavljevic @ 2016-05-23 15:57 UTC (permalink / raw)
  To: Cary Coutant; +Cc: binutils, Petar Jovanovic

> +  // Return whether there is a .reginfo section.
> +  bool
> +  has_reginfo_section() const
> +  { return has_reginfo_section_; }
> 
> Need "this->".

Done.

> @@ -7689,8 +7671,6 @@ Mips_output_section_reginfo<size,
> big_endian>::do_write(Output_file* of)
>    // Write the gp value.
>    elfcpp::Swap<size, big_endian>::writeval(view + 20,
>                                             this->target_->gp_value());
> -
> -  of->write_output_view(offset, data_size, view);
> 
> Why did you remove the call to write_output_view?

I didn't know that this will be implemented in the future.

Thanks for review!

Regards,
Vladimir.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-05-23 15:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-06 15:53 [PATCH][gold] Mips: Fix emitting .reginfo section Vladimir Radosavljevic
2016-05-19 22:51 ` Cary Coutant
2016-05-23 15:57   ` Vladimir Radosavljevic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).