This is the mail archive of the binutils@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]

[PATCH v2 2/4] gold: Correctly get and put r_info for Mips64el.


Nothing is changed. Patch is in attachment.

Regards,
Vladimir.

Changelog -

elfcpp/
	* elfcpp.h (class Rel): Add new constructor.
	(class Rel_write): Likewise.
	(class Rela): Likewise.
	(class Rela_write): Likewise.
	(Rela::get_r_info): Correctly get r_info for Mips64 little endian.
	(Rela_write::put_r_info): Correctly put r_info for Mips64 little endian.

gold/
	* gc.h (gc_process_relocs): Call new constructor for Reltype.
	* target-reloc.h (scan_relocs): Likewise.
	(relocate_section): Likewise.
	(scan_relocatable_relocs): Likewise.
	(relocate_relocs): Call new constructor for Reltype and for Reltype_write.
	* target.h (Target::is_mips64el): New virtual function.
diff --git a/elfcpp/elfcpp.h b/elfcpp/elfcpp.h
index 0e6833f..2dac799 100644
--- a/elfcpp/elfcpp.h
+++ b/elfcpp/elfcpp.h
@@ -1560,13 +1560,20 @@ class Rel
 {
  public:
   Rel(const unsigned char* p)
-    : p_(reinterpret_cast<const internal::Rel_data<size>*>(p))
+    : p_(reinterpret_cast<const internal::Rel_data<size>*>(p)),
+      is_mips64el_(false)
+  { }
+
+  Rel(const unsigned char* p, bool is_mips64el)
+    : p_(reinterpret_cast<const internal::Rel_data<size>*>(p)),
+      is_mips64el_(is_mips64el)
   { }
 
   template<typename File>
   Rel(File* file, typename File::Location loc)
     : p_(reinterpret_cast<const internal::Rel_data<size>*>(
-	   file->view(loc.file_offset, loc.data_size).data()))
+	   file->view(loc.file_offset, loc.data_size).data())),
+	   is_mips64el_(false)
   { }
 
   typename Elf_types<size>::Elf_Addr
@@ -1579,6 +1586,7 @@ class Rel
 
  private:
   const internal::Rel_data<size>* p_;
+  bool is_mips64el_;
 };
 
 // Writer class for an ELF Rel relocation.
@@ -1588,7 +1596,13 @@ class Rel_write
 {
  public:
   Rel_write(unsigned char* p)
-    : p_(reinterpret_cast<internal::Rel_data<size>*>(p))
+    : p_(reinterpret_cast<internal::Rel_data<size>*>(p)),
+      is_mips64el_(false)
+  { }
+
+  Rel_write(unsigned char* p, bool is_mips64el)
+    : p_(reinterpret_cast<internal::Rel_data<size>*>(p)),
+      is_mips64el_(is_mips64el)
   { }
 
   void
@@ -1601,6 +1615,7 @@ class Rel_write
 
  private:
   internal::Rel_data<size>* p_;
+  bool is_mips64el_;
 };
 
 // Accessor class for an ELF Rela relocation.
@@ -1610,13 +1625,20 @@ class Rela
 {
  public:
   Rela(const unsigned char* p)
-    : p_(reinterpret_cast<const internal::Rela_data<size>*>(p))
+    : p_(reinterpret_cast<const internal::Rela_data<size>*>(p)),
+      is_mips64el_(false)
+  { }
+
+  Rela(const unsigned char* p, bool is_mips64el)
+    : p_(reinterpret_cast<const internal::Rela_data<size>*>(p)),
+      is_mips64el_(is_mips64el)
   { }
 
   template<typename File>
   Rela(File* file, typename File::Location loc)
     : p_(reinterpret_cast<const internal::Rela_data<size>*>(
-	   file->view(loc.file_offset, loc.data_size).data()))
+	   file->view(loc.file_offset, loc.data_size).data())),
+	   is_mips64el_(false)
   { }
 
   typename Elf_types<size>::Elf_Addr
@@ -1625,7 +1647,15 @@ class Rela
 
   typename Elf_types<size>::Elf_WXword
   get_r_info() const
-  { return Convert<size, big_endian>::convert_host(this->p_->r_info); }
+  {
+    typename Elf_types<size>::Elf_WXword r_info =
+        Convert<size, big_endian>::convert_host(this->p_->r_info);
+    if (!is_mips64el_)
+      return r_info;
+    return (r_info << 32) | ((r_info >> 8) & 0xff000000)
+           | ((r_info >> 24) & 0x00ff0000) | ((r_info >> 40) & 0x0000ff00)
+           | ((r_info >> 56) & 0x000000ff);
+  }
 
   typename Elf_types<size>::Elf_Swxword
   get_r_addend() const
@@ -1633,6 +1663,7 @@ class Rela
 
  private:
   const internal::Rela_data<size>* p_;
+  bool is_mips64el_;
 };
 
 // Writer class for an ELF Rela relocation.
@@ -1642,7 +1673,13 @@ class Rela_write
 {
  public:
   Rela_write(unsigned char* p)
-    : p_(reinterpret_cast<internal::Rela_data<size>*>(p))
+    : p_(reinterpret_cast<internal::Rela_data<size>*>(p)),
+      is_mips64el_(false)
+  { }
+
+  Rela_write(unsigned char* p, bool is_mips64el)
+    : p_(reinterpret_cast<internal::Rela_data<size>*>(p)),
+      is_mips64el_(is_mips64el)
   { }
 
   void
@@ -1651,7 +1688,16 @@ class Rela_write
 
   void
   put_r_info(typename Elf_types<size>::Elf_WXword v)
-  { this->p_->r_info = Convert<size, big_endian>::convert_host(v); }
+  {
+    typename Elf_types<size>::Elf_WXword r_info =
+        Convert<size, big_endian>::convert_host(v);
+    if (!is_mips64el_)
+      this->p_->r_info = r_info;
+    else
+      this->p_->r_info = (r_info >> 32) | ((r_info & 0xff000000) << 8)
+        | ((r_info & 0x00ff0000) << 24) | ((r_info & 0x0000ff00) << 40)
+        | ((r_info & 0x000000ff) << 56);
+  }
 
   void
   put_r_addend(typename Elf_types<size>::Elf_Swxword v)
@@ -1659,6 +1705,7 @@ class Rela_write
 
  private:
   internal::Rela_data<size>* p_;
+  bool is_mips64el_;
 };
 
 // Accessor classes for entries in the ELF SHT_DYNAMIC section aka
diff --git a/gold/gc.h b/gold/gc.h
index c43fcbe..884650b 100644
--- a/gold/gc.h
+++ b/gold/gc.h
@@ -223,7 +223,7 @@ gc_process_relocs(
 
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
-      Reltype reloc(prelocs);
+      Reltype reloc(prelocs, target->is_mips64el());
       typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
       unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
       unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 89906af..9222161 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -62,7 +62,7 @@ scan_relocs(
 
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
-      Reltype reloc(prelocs);
+      Reltype reloc(prelocs, target->is_mips64el());
 
       if (needs_special_offset_handling
 	  && !output_section->is_input_address_mapped(object, data_shndx,
@@ -281,7 +281,7 @@ relocate_section(
 
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
-      Reltype reloc(prelocs);
+      Reltype reloc(prelocs, target->is_mips64el());
 
       section_offset_type offset =
 	convert_to_section_size_type(reloc.get_r_offset());
@@ -555,7 +555,9 @@ scan_relocatable_relocs(
 
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
-      Reltype reloc(prelocs);
+      bool is_mips64el =
+        parameters->sized_target<size, big_endian>()->is_mips64el();
+      Reltype reloc(prelocs, is_mips64el);
 
       Relocatable_relocs::Reloc_strategy strategy;
 
@@ -657,8 +659,10 @@ relocate_relocs(
 	  pwrite += reloc_size;
 	  continue;
 	}
-      Reltype reloc(prelocs);
-      Reltype_write reloc_write(pwrite);
+      bool is_mips64el =
+        parameters->sized_target<size, big_endian>()->is_mips64el();
+      Reltype reloc(prelocs, is_mips64el);
+      Reltype_write reloc_write(pwrite, is_mips64el);
 
       typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
       const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
diff --git a/gold/target.h b/gold/target.h
index b21c56a..27d9f64 100644
--- a/gold/target.h
+++ b/gold/target.h
@@ -490,6 +490,10 @@ class Target
   should_include_section(elfcpp::Elf_Word sh_type) const
   { return this->do_should_include_section(sh_type); }
 
+  virtual bool
+  is_mips64el() const
+  { return false; }
+
  protected:
   // This struct holds the constant information for a child class.  We
   // use a struct to avoid the overhead of virtual function calls for

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