diff options
author | Rahul Chaudhry <rahulchaudhry@google.com> | 2018-03-27 06:39:27 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-03-27 06:39:27 +0000 |
commit | 369ca62c8ad571067698b8113580315fa63eb190 (patch) | |
tree | 91bfcd6acbf6aaf87d48bae953f64c67aac63385 | |
parent | 7f65d8fed5de8795b736897cfd2345a2b3ece9fc (diff) | |
parent | f1ff343f7f20857b3ca508ee32aaeaaa78bf5795 (diff) | |
download | binutils-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.cc | 22 | ||||
-rw-r--r-- | binutils-2.27/gold/arm.cc | 22 | ||||
-rw-r--r-- | binutils-2.27/gold/x86_64.cc | 34 |
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); |