* 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.
This commit is contained in:
Ian Lance Taylor 2010-01-07 20:43:35 +00:00
parent 3a08d52f28
commit ea715a34a7
9 changed files with 151 additions and 165 deletions

View File

@ -1,3 +1,19 @@
2010-01-07 Ian Lance Taylor <iant@google.com>
* 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.
2010-01-07 Ian Lance Taylor <iant@google.com>
PR 11042

View File

@ -4868,39 +4868,11 @@ Target_arm<big_endian>::do_finalize_sections(
this->set_may_use_blx(true);
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
if (odyn != NULL)
{
if (this->got_plt_ != NULL
&& this->got_plt_->output_section() != NULL)
odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
if (this->plt_ != NULL
&& this->plt_->output_section() != NULL)
{
const Output_data* od = this->plt_->rel_plt();
odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
odyn->add_section_address(elfcpp::DT_JMPREL, od);
odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL);
}
if (this->rel_dyn_ != NULL
&& this->rel_dyn_->output_section() != NULL)
{
const Output_data* od = this->rel_dyn_;
odyn->add_section_address(elfcpp::DT_REL, od);
odyn->add_section_size(elfcpp::DT_RELSZ, od);
odyn->add_constant(elfcpp::DT_RELENT,
elfcpp::Elf_sizes<32>::rel_size);
}
if (!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);
}
}
const Reloc_section* rel_plt = (this->plt_ == NULL
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
this->rel_dyn_, true);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.

View File

@ -1565,40 +1565,11 @@ Target_i386::do_finalize_sections(
const Input_objects*,
Symbol_table* symtab)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
if (odyn != NULL)
{
if (this->got_plt_ != NULL
&& this->got_plt_->output_section() != NULL)
odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
if (this->plt_ != NULL
&& this->plt_->output_section() != NULL)
{
const Output_data* od = this->plt_->rel_plt();
odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
odyn->add_section_address(elfcpp::DT_JMPREL, od);
odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL);
}
if (this->rel_dyn_ != NULL
&& this->rel_dyn_->output_section() != NULL)
{
const Output_data* od = this->rel_dyn_;
odyn->add_section_address(elfcpp::DT_REL, od);
odyn->add_section_size(elfcpp::DT_RELSZ, od);
odyn->add_constant(elfcpp::DT_RELENT,
elfcpp::Elf_sizes<32>::rel_size);
}
if (!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);
}
}
const Reloc_section* rel_plt = (this->plt_ == NULL
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
this->rel_dyn_, true);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.

View File

@ -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

View File

@ -556,6 +556,13 @@ class Layout
incremental_inputs()
{ return this->incremental_inputs_; }
// For the target-specific code to add dynamic tags which are common
// to most targets.
void
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);
// Compute and write out the build ID if needed.
void
write_build_id(Output_file*) const;

View File

@ -206,6 +206,10 @@ class Output_data
output_section()
{ return this->do_output_section(); }
const Output_section*
output_section() const
{ return this->do_output_section(); }
// Return the output section index, if there is an output section.
unsigned int
out_shndx() const
@ -358,6 +362,10 @@ class Output_data
do_output_section()
{ return NULL; }
virtual const Output_section*
do_output_section() const
{ return NULL; }
// Return the output section index, if there is an output section.
virtual unsigned int
do_out_shndx() const
@ -746,6 +754,10 @@ class Output_section_data : public Output_data
do_output_section()
{ return this->output_section_; }
const Output_section*
do_output_section() const
{ return this->output_section_; }
// Return the section index of the output section.
unsigned int
do_out_shndx() const;
@ -2641,6 +2653,10 @@ class Output_section : public Output_data
do_output_section()
{ return this; }
const Output_section*
do_output_section() const
{ return this; }
// Return the section index in the output file.
unsigned int
do_out_shndx() const

View File

@ -1552,37 +1552,11 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
Symbol_table*)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
if (odyn != NULL)
{
if (this->plt_ != NULL
&& this->plt_->output_section() != NULL)
{
const Output_data* od = this->plt_->rel_plt();
odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
odyn->add_section_address(elfcpp::DT_JMPREL, od);
odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
}
if (this->rela_dyn_ != NULL
&& this->rela_dyn_->output_section() != NULL)
{
const Output_data* od = this->rela_dyn_;
odyn->add_section_address(elfcpp::DT_RELA, od);
odyn->add_section_size(elfcpp::DT_RELASZ, od);
odyn->add_constant(elfcpp::DT_RELAENT,
elfcpp::Elf_sizes<size>::rela_size);
}
if (!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);
}
}
const Reloc_section* rel_plt = (this->plt_ == NULL
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
this->rela_dyn_, true);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.

View File

@ -2331,37 +2331,11 @@ Target_sparc<size, big_endian>::do_finalize_sections(
Symbol_table*)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
if (odyn != NULL)
{
if (this->plt_ != NULL
&& this->plt_->output_section() != NULL)
{
const Output_data* od = this->plt_->rel_plt();
odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
odyn->add_section_address(elfcpp::DT_JMPREL, od);
odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
}
if (this->rela_dyn_ != NULL
&& this->rela_dyn_->output_section() != NULL)
{
const Output_data* od = this->rela_dyn_;
odyn->add_section_address(elfcpp::DT_RELA, od);
odyn->add_section_size(elfcpp::DT_RELASZ, od);
odyn->add_constant(elfcpp::DT_RELAENT,
elfcpp::Elf_sizes<size>::rela_size);
}
if (!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);
}
}
const Reloc_section* rel_plt = (this->plt_ == NULL
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
this->rela_dyn_, true);
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.

View File

@ -1655,22 +1655,19 @@ Target_x86_64::do_finalize_sections(
const Input_objects*,
Symbol_table* symtab)
{
const Reloc_section* rel_plt = (this->plt_ == NULL
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
this->rela_dyn_, true);
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
if (odyn != NULL)
{
if (this->got_plt_ != NULL
&& this->got_plt_->output_section() != NULL)
odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
if (this->plt_ != NULL
&& this->plt_->output_section() != NULL)
{
const Output_data* od = this->plt_->rel_plt();
odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
odyn->add_section_address(elfcpp::DT_JMPREL, od);
odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
if (this->plt_->has_tlsdesc_entry())
&& this->plt_->output_section() != NULL
&& this->plt_->has_tlsdesc_entry())
{
unsigned int plt_offset = this->plt_->get_tlsdesc_plt_offset();
unsigned int got_offset = this->plt_->get_tlsdesc_got_offset();
@ -1682,24 +1679,6 @@ Target_x86_64::do_finalize_sections(
}
}
if (this->rela_dyn_ != NULL
&& this->rela_dyn_->output_section() != NULL)
{
const Output_data* od = this->rela_dyn_;
odyn->add_section_address(elfcpp::DT_RELA, od);
odyn->add_section_size(elfcpp::DT_RELASZ, od);
odyn->add_constant(elfcpp::DT_RELAENT,
elfcpp::Elf_sizes<64>::rela_size);
}
if (!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);
}
}
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.
if (this->copy_relocs_.any_saved_relocs())