2010-01-22 Doug Kwan <dougkwan@google.com>

* arm.cc (Target_arm::do_relax): Record an output section for section
	offset adjustment it contains any stub table that has changed.
	* layout.cc (Layout::clean_up_after_relaxation): Adjust section
	offsets in an output section if necessary.
	* output.cc (Output_section::Output_section): Initialize
	section_offsets_need_adjustments_.
	(Output_section::add_input_section_for_script): Renamed to
	Output_section::add_simple_input_section.
	(Output_section::save_states): Add a comment.
	(Output_section::discard_states): New method defintion.
	(Output_section::adjust_section_offsets): Same.
	* output.h (Output_section::add_input_section_for_script): Renamed to
	Output_section::add_simple_input_section.
	(Output_section::discard_states): New method declaration.
	(Output_section::adjust_section_offsets): Same.
	(Output_section::section_offsets_need_adjustment,
	Output_section::set_section_offsets_need_adjustment): New method
	definitions.
	(Output_section::section_offsets_need_adjustment_): New data member.
	* script-sections.cc
	(Output_section_element_input::set_section_address): Adjust code for
	renaming of Output_section::add_input_section_for_script.
	(Orphan_output_section::set_section_address): Same.
This commit is contained in:
Doug Kwan 2010-01-23 01:07:59 +00:00
parent 767acc28c1
commit 8923b24c4b
6 changed files with 129 additions and 14 deletions

View File

@ -1,3 +1,29 @@
2010-01-22 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::do_relax): Record an output section for section
offset adjustment it contains any stub table that has changed.
* layout.cc (Layout::clean_up_after_relaxation): Adjust section
offsets in an output section if necessary.
* output.cc (Output_section::Output_section): Initialize
section_offsets_need_adjustments_.
(Output_section::add_input_section_for_script): Renamed to
Output_section::add_simple_input_section.
(Output_section::save_states): Add a comment.
(Output_section::discard_states): New method defintion.
(Output_section::adjust_section_offsets): Same.
* output.h (Output_section::add_input_section_for_script): Renamed to
Output_section::add_simple_input_section.
(Output_section::discard_states): New method declaration.
(Output_section::adjust_section_offsets): Same.
(Output_section::section_offsets_need_adjustment,
Output_section::set_section_offsets_need_adjustment): New method
definitions.
(Output_section::section_offsets_need_adjustment_): New data member.
* script-sections.cc
(Output_section_element_input::set_section_address): Adjust code for
renaming of Output_section::add_input_section_for_script.
(Orphan_output_section::set_section_address): Same.
2010-01-22 Viktor Kutuzov <vkutuzov@accesssoftek.com>
* gold/arm.cc (Target_arm): Updated fix_v4bx method and usage of

View File

@ -8716,13 +8716,37 @@ Target_arm<big_endian>::do_relax(
// or addresses alignments changed. These are the only things that
// matter.
bool any_stub_table_changed = false;
Unordered_set<const Output_section*> sections_needing_adjustment;
for (Stub_table_iterator sp = this->stub_tables_.begin();
(sp != this->stub_tables_.end()) && !any_stub_table_changed;
++sp)
{
if ((*sp)->update_data_size_and_addralign())
{
// Update data size of stub table owner.
Arm_input_section<big_endian>* owner = (*sp)->owner();
uint64_t address = owner->address();
off_t offset = owner->offset();
owner->reset_address_and_file_offset();
owner->set_address_and_file_offset(address, offset);
sections_needing_adjustment.insert(owner->output_section());
any_stub_table_changed = true;
}
}
// Output_section_data::output_section() returns a const pointer but we
// need to update output sections, so we record all output sections needing
// update above and scan the sections here to find out what sections need
// to be updated.
for(Layout::Section_list::const_iterator p = layout->section_list().begin();
p != layout->section_list().end();
++p)
{
if (sections_needing_adjustment.find(*p)
!= sections_needing_adjustment.end())
(*p)->set_section_offsets_need_adjustment();
}
// Finalize the stubs in the last relaxation pass.
if (!any_stub_table_changed)

View File

@ -1401,8 +1401,15 @@ Layout::clean_up_after_relaxation()
p != this->section_list_.end();
++p)
{
(*p)->reset_address_and_file_offset();
(*p)->restore_states();
// If an input section changes size because of relaxation,
// we need to adjust the section offsets of all input sections.
// after such a section.
if ((*p)->section_offsets_need_adjustment())
(*p)->adjust_section_offsets();
(*p)->reset_address_and_file_offset();
}
// Reset special output object address and file offsets.

View File

@ -1890,6 +1890,7 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
is_dynamic_linker_section_(false),
generate_code_fills_at_write_(false),
is_entsize_zero_(false),
section_offsets_need_adjustment_(false),
tls_offset_(0),
checkpoint_(NULL),
merge_section_map_(),
@ -3043,10 +3044,10 @@ Output_section::get_input_sections(
return data_size;
}
// Add an input section from a script.
// Add an simple input section.
void
Output_section::add_input_section_for_script(const Simple_input_section& sis,
Output_section::add_simple_input_section(const Simple_input_section& sis,
off_t data_size,
uint64_t addralign)
{
@ -3067,7 +3068,7 @@ Output_section::add_input_section_for_script(const Simple_input_section& sis,
this->input_sections_.push_back(is);
}
//
// Save states for relaxation.
void
Output_section::save_states()
@ -3082,6 +3083,19 @@ Output_section::save_states()
gold_assert(this->fills_.empty());
}
void
Output_section::discard_states()
{
gold_assert(this->checkpoint_ != NULL);
delete this->checkpoint_;
this->checkpoint_ = NULL;
gold_assert(this->fills_.empty());
// Simply invalidate the relaxed input section map since we do not keep
// track of it.
this->is_relaxed_input_section_map_valid_ = false;
}
void
Output_section::restore_states()
{
@ -3116,6 +3130,29 @@ Output_section::restore_states()
this->is_relaxed_input_section_map_valid_ = false;
}
// Update the section offsets of input sections in this. This is required if
// relaxation causes some input sections to change sizes.
void
Output_section::adjust_section_offsets()
{
if (!this->section_offsets_need_adjustment_)
return;
off_t off = 0;
for (Input_section_list::iterator p = this->input_sections_.begin();
p != this->input_sections_.end();
++p)
{
off = align_address(off, p->addralign());
if (p->is_input_section())
p->relobj()->set_section_offset(p->shndx(), off);
off += p->data_size();
}
this->section_offsets_need_adjustment_ = false;
}
// Print to the map file.
void

View File

@ -2718,9 +2718,9 @@ class Output_section : public Output_data
get_input_sections(uint64_t address, const std::string& fill,
std::list<Simple_input_section>*);
// Add an input section from a script.
// Add a simple input section.
void
add_input_section_for_script(const Simple_input_section& input_section,
add_simple_input_section(const Simple_input_section& input_section,
off_t data_size, uint64_t addralign);
// Set the current size of the output section.
@ -2744,6 +2744,10 @@ class Output_section : public Output_data
void
restore_states();
// Discard states.
void
discard_states();
// Convert existing input sections to relaxed input sections.
void
convert_input_sections_to_relaxed_sections(
@ -2754,6 +2758,21 @@ class Output_section : public Output_data
const Output_relaxed_input_section*
find_relaxed_input_section(const Relobj* object, unsigned int shndx) const;
// Whether section offsets need adjustment due to relaxation.
bool
section_offsets_need_adjustment() const
{ return this->section_offsets_need_adjustment_; }
// Set section_offsets_need_adjustment to be true.
void
set_section_offsets_need_adjustment()
{ this->section_offsets_need_adjustment_ = true; }
// Adjust section offsets of input sections in this. This is
// requires if relaxation caused some input sections to change sizes.
void
adjust_section_offsets();
// Print merge statistics to stderr.
void
print_merge_stats();
@ -3509,6 +3528,8 @@ class Output_section : public Output_data
bool generate_code_fills_at_write_ : 1;
// Whether the entry size field should be zero.
bool is_entsize_zero_ : 1;
// Whether section offsets need adjustment due to relaxation.
bool section_offsets_need_adjustment_ : 1;
// For SHT_TLS sections, the offset of this section relative to the base
// of the TLS segment.
uint64_t tls_offset_;

View File

@ -1409,7 +1409,7 @@ Output_section_element_input::set_section_addresses(
layout->new_output_section_data_from_script(posd);
}
output_section->add_input_section_for_script(p->input_section(),
output_section->add_simple_input_section(p->input_section(),
p->size(),
this_subalign);
@ -2315,7 +2315,7 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
}
address = align_address(address, addralign);
this->os_->add_input_section_for_script(*p, size, addralign);
this->os_->add_simple_input_section(*p, size, addralign);
address += size;
}