summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRahul Chaudhry <rahulchaudhry@google.com>2018-03-27 06:39:27 +0000
committerandroid-build-merger <android-build-merger@google.com>2018-03-27 06:39:27 +0000
commit369ca62c8ad571067698b8113580315fa63eb190 (patch)
tree91bfcd6acbf6aaf87d48bae953f64c67aac63385
parent7f65d8fed5de8795b736897cfd2345a2b3ece9fc (diff)
parentf1ff343f7f20857b3ca508ee32aaeaaa78bf5795 (diff)
downloadbinutils-369ca62c8ad571067698b8113580315fa63eb190.tar.gz
gold: add support for relative relocations at odd offsets. am: b162eb11c3
am: f1ff343f7f Change-Id: I2bebcd2a3a6fc88f8865dce8db6051a1b4344407
-rw-r--r--binutils-2.27/gold/aarch64.cc22
-rw-r--r--binutils-2.27/gold/arm.cc22
-rw-r--r--binutils-2.27/gold/x86_64.cc34
3 files changed, 49 insertions, 29 deletions
diff --git a/binutils-2.27/gold/aarch64.cc b/binutils-2.27/gold/aarch64.cc
index 2b3d3a8e..ebddeb6c 100644
--- a/binutils-2.27/gold/aarch64.cc
+++ b/binutils-2.27/gold/aarch64.cc
@@ -6132,11 +6132,13 @@ Target_aarch64<size, big_endian>::Scan::local(
// reloction, so that the dynamic loader can relocate it.
if (parameters->options().output_is_position_independent())
{
- if (parameters->options().experimental_use_relr())
+ Address r_offset = rela.get_r_offset();
+ if (parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn = target->relr_dyn_section(layout);
relr_dyn->add_local_relative(object, r_sym, output_section,
- data_shndx, rela.get_r_offset());
+ data_shndx, r_offset);
}
else
{
@@ -6144,7 +6146,7 @@ Target_aarch64<size, big_endian>::Scan::local(
rela_dyn->add_local_relative(object, r_sym,
elfcpp::R_AARCH64_RELATIVE,
output_section, data_shndx,
- rela.get_r_offset(),
+ r_offset,
rela.get_r_addend(),
is_ifunc);
}
@@ -6173,7 +6175,8 @@ Target_aarch64<size, big_endian>::Scan::local(
{
unsigned int got_offset =
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
- if (parameters->options().experimental_use_relr())
+ if (parameters->options().experimental_use_relr()
+ && got_offset%2 == 0)
{
Relr_section* relr_dyn = target->relr_dyn_section(layout);
relr_dyn->add_local_relative(object, r_sym, got, got_offset);
@@ -6441,13 +6444,15 @@ Target_aarch64<size, big_endian>::Scan::global(
else if (r_type == elfcpp::R_AARCH64_ABS64
&& gsym->can_use_relative_reloc(false))
{
- if (parameters->options().experimental_use_relr())
+ Address r_offset = rela.get_r_offset();
+ if (parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
relr_dyn->add_global_relative(gsym, output_section,
object, data_shndx,
- rela.get_r_offset());
+ r_offset);
}
else
{
@@ -6456,7 +6461,7 @@ Target_aarch64<size, big_endian>::Scan::global(
elfcpp::R_AARCH64_RELATIVE,
output_section, object,
data_shndx,
- rela.get_r_offset(),
+ r_offset,
rela.get_r_addend(),
false);
}
@@ -6571,7 +6576,8 @@ Target_aarch64<size, big_endian>::Scan::global(
if (is_new)
{
unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
- if (parameters->options().experimental_use_relr())
+ if (parameters->options().experimental_use_relr()
+ && got_off%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
diff --git a/binutils-2.27/gold/arm.cc b/binutils-2.27/gold/arm.cc
index 2dcb104d..a56d71d6 100644
--- a/binutils-2.27/gold/arm.cc
+++ b/binutils-2.27/gold/arm.cc
@@ -8537,11 +8537,13 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
if (parameters->options().output_is_position_independent())
{
unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
- if (parameters->options().experimental_use_relr())
+ Arm_address r_offset = reloc.get_r_offset();
+ if (parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn = target->relr_dyn_section(layout);
relr_dyn->add_local_relative(object, r_sym, output_section,
- data_shndx, reloc.get_r_offset());
+ data_shndx, r_offset);
}
else
{
@@ -8550,7 +8552,7 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
// we need to add check_non_pic(object, r_type) here.
rel_dyn->add_local_relative(object, r_sym, elfcpp::R_ARM_RELATIVE,
output_section, data_shndx,
- reloc.get_r_offset(), is_ifunc);
+ r_offset, is_ifunc);
}
}
break;
@@ -8677,7 +8679,8 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
unsigned int got_offset =
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
- if (parameters->options().experimental_use_relr())
+ if (parameters->options().experimental_use_relr()
+ && got_offset%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
@@ -8999,13 +9002,15 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
|| r_type == elfcpp::R_ARM_ABS32_NOI)
&& gsym->can_use_relative_reloc(false))
{
- if (parameters->options().experimental_use_relr())
+ Arm_address r_offset = reloc.get_r_offset();
+ if (parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
relr_dyn->add_global_relative(gsym, output_section,
object, data_shndx,
- reloc.get_r_offset());
+ r_offset);
}
else
{
@@ -9013,7 +9018,7 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE,
output_section, object,
data_shndx,
- reloc.get_r_offset());
+ r_offset);
}
}
else
@@ -9183,7 +9188,8 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
if (is_new)
{
unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
- if (parameters->options().experimental_use_relr())
+ if (parameters->options().experimental_use_relr()
+ && got_off%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
diff --git a/binutils-2.27/gold/x86_64.cc b/binutils-2.27/gold/x86_64.cc
index 7b736188..84e94bcf 100644
--- a/binutils-2.27/gold/x86_64.cc
+++ b/binutils-2.27/gold/x86_64.cc
@@ -445,6 +445,7 @@ class Target_x86_64 : public Sized_target<size, false>
// uses only Elf64_Rela relocation entries with explicit addends."
typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, false> Reloc_section;
typedef Output_data_reloc<elfcpp::SHT_RELR, true, size, false> Relr_section;
+ typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
Target_x86_64(const Target::Target_info* info = &x86_64_info)
: Sized_target<size, false>(info),
@@ -2547,13 +2548,15 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
if (parameters->options().output_is_position_independent())
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
+ Address r_offset = reloc.get_r_offset();
if (size == 64
&& !is_ifunc
- && parameters->options().experimental_use_relr())
+ && parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn = target->relr_dyn_section(layout);
relr_dyn->add_local_relative(object, r_sym, output_section,
- data_shndx, reloc.get_r_offset());
+ data_shndx, r_offset);
}
else
{
@@ -2563,7 +2566,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
? elfcpp::R_X86_64_RELATIVE64
: elfcpp::R_X86_64_RELATIVE),
output_section, data_shndx,
- reloc.get_r_offset(),
+ r_offset,
reloc.get_r_addend(), is_ifunc);
}
}
@@ -2583,12 +2586,14 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
if (size == 32 && r_type == elfcpp::R_X86_64_32)
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
- if (!is_ifunc && parameters->options().experimental_use_relr())
+ Address r_offset = reloc.get_r_offset();
+ if (!is_ifunc
+ && parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn = target->relr_dyn_section(layout);
relr_dyn->add_local_relative(object, r_sym, output_section,
- data_shndx,
- reloc.get_r_offset());
+ data_shndx, r_offset);
}
else
{
@@ -2596,7 +2601,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
rela_dyn->add_local_relative(object, r_sym,
elfcpp::R_X86_64_RELATIVE,
output_section, data_shndx,
- reloc.get_r_offset(),
+ r_offset,
reloc.get_r_addend(), is_ifunc);
}
break;
@@ -2714,7 +2719,8 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
}
else if (size == 64
&& !is_ifunc
- && parameters->options().experimental_use_relr())
+ && parameters->options().experimental_use_relr()
+ && got_offset%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
@@ -3089,13 +3095,15 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
|| (size == 32 && r_type == elfcpp::R_X86_64_32))
&& gsym->can_use_relative_reloc(false))
{
- if (parameters->options().experimental_use_relr())
+ Address r_offset = reloc.get_r_offset();
+ if (parameters->options().experimental_use_relr()
+ && r_offset%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);
relr_dyn->add_global_relative(gsym, output_section,
object, data_shndx,
- reloc.get_r_offset());
+ r_offset);
}
else
{
@@ -3103,8 +3111,7 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
rela_dyn->add_global_relative(gsym,
elfcpp::R_X86_64_RELATIVE,
output_section, object,
- data_shndx,
- reloc.get_r_offset(),
+ data_shndx, r_offset,
reloc.get_r_addend(), false);
}
}
@@ -3238,7 +3245,8 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
if (is_new)
{
unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
- if (parameters->options().experimental_use_relr())
+ if (parameters->options().experimental_use_relr()
+ && got_off%2 == 0)
{
Relr_section* relr_dyn =
target->relr_dyn_section(layout);