diff options
author | Ian Lance Taylor <ian@airs.com> | 2010-01-07 20:43:35 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2010-01-07 20:43:35 +0000 |
commit | ea715a34a7803993d232d8b85dbd77ca537190e6 (patch) | |
tree | 4fbc5d6e8c0a59a68e16dda8cb19459ec0c76bfa /gold/layout.cc | |
parent | 3a08d52f28cafb9fca077d58be4f0cdb42f3f655 (diff) | |
download | binutils-ea715a34a7803993d232d8b85dbd77ca537190e6.zip binutils-ea715a34a7803993d232d8b85dbd77ca537190e6.tar.gz binutils-ea715a34a7803993d232d8b85dbd77ca537190e6.tar.bz2 |
* output.h (class Output_data): Add const version of
output_section and do_output_section.
(class Output_section_data): Add const version of
do_output_section.
(class Output_section): Likewise.
* layout.cc (Layout::add_target_dynamic_tags): New function.
* layout.h (class Layout): Update declarations.
* arm.cc (Target_arm::do_finalize_sections): Use
add_target_dynamic_tags.
* i386.cc (Target_i386::do_finalize_sections): Likewise.
* powerpc.cc (Target_powerpc::do_finalize_sections): Likewise.
* sparc.cc (Target_sparc::do_finalize_sections): Likewise.
* x86_64.cc (Target_x86_64::do_finalize_sections): Likewise.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r-- | gold/layout.cc | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/gold/layout.cc b/gold/layout.cc index 9f51e82..a55020c 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -3206,6 +3206,83 @@ Layout::create_interp(const Target* target) } } +// Add dynamic tags for the PLT and the dynamic relocs. This is +// called by the target-specific code. This does nothing if not doing +// a dynamic link. + +// USE_REL is true for REL relocs rather than RELA relocs. + +// If PLT_GOT is not NULL, then DT_PLTGOT points to it. + +// If PLT_REL is not NULL, it is used for DT_PLTRELSZ, and DT_JMPREL, +// and we also set DT_PLTREL. + +// If DYN_REL is not NULL, it is used for DT_REL/DT_RELA, +// DT_RELSZ/DT_RELASZ, DT_RELENT/DT_RELAENT. + +// If ADD_DEBUG is true, we add a DT_DEBUG entry when generating an +// executable. + +void +Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got, + const Output_data* plt_rel, + const Output_data* dyn_rel, bool add_debug) +{ + Output_data_dynamic* odyn = this->dynamic_data_; + if (odyn == NULL) + return; + + if (plt_got != NULL && plt_got->output_section() != NULL) + odyn->add_section_address(elfcpp::DT_PLTGOT, plt_got); + + if (plt_rel != NULL && plt_rel->output_section() != NULL) + { + odyn->add_section_size(elfcpp::DT_PLTRELSZ, plt_rel); + odyn->add_section_address(elfcpp::DT_JMPREL, plt_rel); + odyn->add_constant(elfcpp::DT_PLTREL, + use_rel ? elfcpp::DT_REL : elfcpp::DT_RELA); + } + + if (dyn_rel != NULL && dyn_rel->output_section() != NULL) + { + odyn->add_section_address(use_rel ? elfcpp::DT_REL : elfcpp::DT_RELA, + dyn_rel); + odyn->add_section_size(use_rel ? elfcpp::DT_RELSZ : elfcpp::DT_RELASZ, + dyn_rel); + const int size = parameters->target().get_size(); + elfcpp::DT rel_tag; + int rel_size; + if (use_rel) + { + rel_tag = elfcpp::DT_RELENT; + if (size == 32) + rel_size = Reloc_types<elfcpp::SHT_REL, 32, false>::reloc_size; + else if (size == 64) + rel_size = Reloc_types<elfcpp::SHT_REL, 64, false>::reloc_size; + else + gold_unreachable(); + } + else + { + rel_tag = elfcpp::DT_RELAENT; + if (size == 32) + rel_size = Reloc_types<elfcpp::SHT_RELA, 32, false>::reloc_size; + else if (size == 64) + rel_size = Reloc_types<elfcpp::SHT_RELA, 64, false>::reloc_size; + else + gold_unreachable(); + } + odyn->add_constant(rel_tag, rel_size); + } + + if (add_debug && !parameters->options().shared()) + { + // The value of the DT_DEBUG tag is filled in by the dynamic + // linker at run time, and used by the debugger. + odyn->add_constant(elfcpp::DT_DEBUG, 0); + } +} + // Finish the .dynamic section and PT_DYNAMIC segment. void |