This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH v2 2/4] gold: Correctly get and put r_info for Mips64el.
- From: Vladimir Radosavljevic <Vladimir dot Radosavljevic at imgtec dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: Petar Jovanovic <Petar dot Jovanovic at imgtec dot com>
- Date: Wed, 18 Nov 2015 15:59:55 +0000
- Subject: [PATCH v2 2/4] gold: Correctly get and put r_info for Mips64el.
- Authentication-results: sourceware.org; auth=none
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