From: Cary Coutant Date: Wed, 31 Jul 2013 18:47:50 +0000 (+0000) Subject: gold/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c6905c28a51b6716f2d0243a76825e2dd6ad59de;p=binutils-gdb.git gold/ * object.cc (Sized_relobj::do_output_section_address): New function. (Sized_relobj): Instantiate explicitly. * object.h (Object::output_section_address): New function. (Object::do_output_section_address): New function. (Sized_relobj::do_output_section_address): New function. * powerpc.cc (Target_powerpc::symval_for_branch): Use it. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index b4b46873082..1bbeda4d5f5 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,4 +1,13 @@ -2013-07-23 Cary Coutant +2013-07-31 Cary Coutant + + * object.cc (Sized_relobj::do_output_section_address): New function. + (Sized_relobj): Instantiate explicitly. + * object.h (Object::output_section_address): New function. + (Object::do_output_section_address): New function. + (Sized_relobj::do_output_section_address): New function. + * powerpc.cc (Target_powerpc::symval_for_branch): Use it. + +2013-07-30 Cary Coutant Sasa Stankovic * parameters.cc (Parameters::entry): Return target-specific entry diff --git a/gold/object.cc b/gold/object.cc index 1f113d14fac..c98b3c5a773 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -389,6 +389,23 @@ Sized_relobj::do_for_all_local_got_entries( } } +// Get the address of an output section. + +template +uint64_t +Sized_relobj::do_output_section_address( + unsigned int shndx) +{ + // If the input file is linked as --just-symbols, the output + // section address is the input section address. + if (this->just_symbols()) + return this->section_address(shndx); + + const Output_section* os = this->do_output_section(shndx); + gold_assert(os != NULL); + return os->address(); +} + // Class Sized_relobj_file. template @@ -3216,21 +3233,33 @@ Object::find_shdr<64,true>(const unsigned char*, const char*, const char*, #endif #ifdef HAVE_TARGET_32_LITTLE +template +class Sized_relobj<32, false>; + template class Sized_relobj_file<32, false>; #endif #ifdef HAVE_TARGET_32_BIG +template +class Sized_relobj<32, true>; + template class Sized_relobj_file<32, true>; #endif #ifdef HAVE_TARGET_64_LITTLE +template +class Sized_relobj<64, false>; + template class Sized_relobj_file<64, false>; #endif #ifdef HAVE_TARGET_64_BIG +template +class Sized_relobj<64, true>; + template class Sized_relobj_file<64, true>; #endif diff --git a/gold/object.h b/gold/object.h index c17c13d2856..ae6d9bf4d31 100644 --- a/gold/object.h +++ b/gold/object.h @@ -551,6 +551,13 @@ class Object output_section(unsigned int shndx) const { return this->do_output_section(shndx); } + // Given a section index, return its address. + // The return value will be -1U if the section is specially mapped, + // such as a merge section. + uint64_t + output_section_address(unsigned int shndx) + { return this->do_output_section_address(shndx); } + // Given a section index, return the offset in the Output_section. // The return value will be -1U if the section is specially mapped, // such as a merge section. @@ -852,6 +859,11 @@ class Object do_output_section(unsigned int) const { gold_unreachable(); } + // Get the address of a section--implemented by child class. + virtual uint64_t + do_output_section_address(unsigned int) + { gold_unreachable(); } + // Get the offset of a section--implemented by child class. virtual uint64_t do_output_section_offset(unsigned int) const @@ -1929,6 +1941,10 @@ class Sized_relobj : public Relobj section_offsets() { return this->section_offsets_; } + // Get the address of an output section. + uint64_t + do_output_section_address(unsigned int shndx); + // Get the offset of a section. uint64_t do_output_section_offset(unsigned int shndx) const diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 676aad6f181..1afe01c4bfb 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -6203,7 +6203,7 @@ Target_powerpc::symval_for_branch( Address opd_addr = symobj->get_output_section_offset(shndx); if (opd_addr == invalid_address) return value; - opd_addr += symobj->output_section(shndx)->address(); + opd_addr += symobj->output_section_address(shndx); if (value >= opd_addr && value < opd_addr + symobj->section_size(shndx)) { Address sec_off;