2010-05-14 Doug Kwan <dougkwan@google.com>

* arm.cc (Arm_input_section::original_size): New method.
	(Arm_input_section::do_addralign): Add a cast.
	(Arm_input_section::do_output_offset): Remove static cast.
	(Arm_input_section::original_addralign,
	 Arm_input_section::original_size_): Change type to uint32_t.
	(Arm_input_section::init): Add safe casts for section alignment
	and size.
	(Arm_input_section::set_final_data_size): Do not set address and
	offset of stub table.
	(Arm_output_section::fix_exidx_coverage): Change use of of
	Output_section::Simple_input_section to that of
	Output_section::Input_section.
	(Target_arm::do_relax): Set addresses and file offsets of Stub_tables
	except for the first pass.
	* output.cc (Output_section::get_input_sections): Change type of
	input_sections to std::list<Input_section>.
	(Output_section::add_script_input_section): Rename from
	Output_section::add_simple_input_section.  Change type of SIS
	parameter from Simple_input_section to Input_section.
	* output.h (Output_section::Simple_input_section): Remove class.
	(Output_section::Input_section): Change class visibility to public.
	(Output_section::Input_section::addralign): Use stored alignments
	for special input sections if set.
	(Output_section::Input_section::set_addralign): New method.
	(Output_section::get_input_sections): Change parameter type from
	list of Simple_input_section to list of Input_section.
	(Output_section::add_script_input_section): Rename from
	Output_section::add_simple_input_section. Change first parameter's
	type from Simple_input_section to Input_section and remove the
	second and third parameters.
	* script-sections.cc (Input_section::Input_section_list): Change
	type to list of Output_section::Input_section/
	(Input_section_info::Input_section_info): Change parameter type of
	INPUT_SECTION to Output_section::Input_section.
	(Input_section_info::input_section): Change return type.
	(Input_section_info::input_section_): Change type to
	Output_section::Input_section.
	(Output_section_element_input::set_section_addresses): Adjust code
	to use Output_section::Input_section instead of
	Output_section::Simple_input_section.  Adjust code for renaming
	of Output_section::add_simple_input_section.
	(Orphan_output_section::set_section_addresses): Ditto.
This commit is contained in:
Doug Kwan 2010-05-19 07:09:36 +00:00
parent 51b5d4a8c5
commit 6625d24e23
5 changed files with 339 additions and 328 deletions

View File

@ -1,3 +1,48 @@
2010-05-19 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_input_section::original_size): New method.
(Arm_input_section::do_addralign): Add a cast.
(Arm_input_section::do_output_offset): Remove static cast.
(Arm_input_section::original_addralign,
Arm_input_section::original_size_): Change type to uint32_t.
(Arm_input_section::init): Add safe casts for section alignment
and size.
(Arm_input_section::set_final_data_size): Do not set address and
offset of stub table.
(Arm_output_section::fix_exidx_coverage): Change use of of
Output_section::Simple_input_section to that of
Output_section::Input_section.
(Target_arm::do_relax): Set addresses and file offsets of Stub_tables
except for the first pass.
* output.cc (Output_section::get_input_sections): Change type of
input_sections to std::list<Input_section>.
(Output_section::add_script_input_section): Rename from
Output_section::add_simple_input_section. Change type of SIS
parameter from Simple_input_section to Input_section.
* output.h (Output_section::Simple_input_section): Remove class.
(Output_section::Input_section): Change class visibility to public.
(Output_section::Input_section::addralign): Use stored alignments
for special input sections if set.
(Output_section::Input_section::set_addralign): New method.
(Output_section::get_input_sections): Change parameter type from
list of Simple_input_section to list of Input_section.
(Output_section::add_script_input_section): Rename from
Output_section::add_simple_input_section. Change first parameter's
type from Simple_input_section to Input_section and remove the
second and third parameters.
* script-sections.cc (Input_section::Input_section_list): Change
type to list of Output_section::Input_section/
(Input_section_info::Input_section_info): Change parameter type of
INPUT_SECTION to Output_section::Input_section.
(Input_section_info::input_section): Change return type.
(Input_section_info::input_section_): Change type to
Output_section::Input_section.
(Output_section_element_input::set_section_addresses): Adjust code
to use Output_section::Input_section instead of
Output_section::Simple_input_section. Adjust code for renaming
of Output_section::add_simple_input_section.
(Orphan_output_section::set_section_addresses): Ditto.
2010-05-18 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* gold.h (Unordered_multimap, Unordered_map): Fix defines for

View File

@ -1164,6 +1164,11 @@ class Arm_input_section : public Output_relaxed_input_section
as_arm_input_section(Output_relaxed_input_section* poris)
{ return static_cast<Arm_input_section<big_endian>*>(poris); }
// Return the original size of the section.
uint32_t
original_size() const
{ return this->original_size_; }
protected:
// Write data to output file.
void
@ -1175,7 +1180,7 @@ class Arm_input_section : public Output_relaxed_input_section
{
if (this->is_stub_table_owner())
return std::max(this->stub_table_->addralign(),
this->original_addralign_);
static_cast<uint64_t>(this->original_addralign_));
else
return this->original_addralign_;
}
@ -1197,8 +1202,7 @@ class Arm_input_section : public Output_relaxed_input_section
if ((object == this->relobj())
&& (shndx == this->shndx())
&& (offset >= 0)
&& (convert_types<uint64_t, section_offset_type>(offset)
<= this->original_size_))
&& (offset <= this->original_size_))
{
*poutput = offset;
return true;
@ -1213,9 +1217,9 @@ class Arm_input_section : public Output_relaxed_input_section
Arm_input_section& operator=(const Arm_input_section&);
// Address alignment of the original input section.
uint64_t original_addralign_;
uint32_t original_addralign_;
// Section size of the original input section.
uint64_t original_size_;
uint32_t original_size_;
// Stub table.
Stub_table<big_endian>* stub_table_;
};
@ -4909,8 +4913,10 @@ Arm_input_section<big_endian>::init()
// Cache these to speed up size and alignment queries. It is too slow
// to call section_addraglin and section_size every time.
this->original_addralign_ = relobj->section_addralign(shndx);
this->original_size_ = relobj->section_size(shndx);
this->original_addralign_ =
convert_types<uint32_t, uint64_t>(relobj->section_addralign(shndx));
this->original_size_ =
convert_types<uint32_t, uint64_t>(relobj->section_size(shndx));
// We want to make this look like the original input section after
// output sections are finalized.
@ -4949,10 +4955,8 @@ Arm_input_section<big_endian>::set_final_data_size()
if (this->is_stub_table_owner())
{
// The stub table comes after the original section contents.
this->stub_table_->finalize_data_size();
off = align_address(off, this->stub_table_->addralign());
this->stub_table_->set_address_and_file_offset(this->address() + off,
this->offset() + off);
off += this->stub_table_->data_size();
}
this->set_data_size(off);
@ -5576,8 +5580,8 @@ Arm_output_section<big_endian>::fix_exidx_coverage(
// Remove all input sections.
uint64_t address = this->address();
typedef std::list<Simple_input_section> Simple_input_section_list;
Simple_input_section_list input_sections;
typedef std::list<Output_section::Input_section> Input_section_list;
Input_section_list input_sections;
this->reset_address_and_file_offset();
this->get_input_sections(address, std::string(""), &input_sections);
@ -5586,20 +5590,23 @@ Arm_output_section<big_endian>::fix_exidx_coverage(
// Go through all the known input sections and record them.
typedef Unordered_set<Section_id, Section_id_hash> Section_id_set;
Section_id_set known_input_sections;
for (Simple_input_section_list::const_iterator p = input_sections.begin();
typedef Unordered_map<Section_id, const Output_section::Input_section*,
Section_id_hash> Text_to_exidx_map;
Text_to_exidx_map text_to_exidx_map;
for (Input_section_list::const_iterator p = input_sections.begin();
p != input_sections.end();
++p)
{
// This should never happen. At this point, we should only see
// plain EXIDX input sections.
gold_assert(!p->is_relaxed_input_section());
known_input_sections.insert(Section_id(p->relobj(), p->shndx()));
text_to_exidx_map[Section_id(p->relobj(), p->shndx())] = &(*p);
}
Arm_exidx_fixup exidx_fixup(this, merge_exidx_entries);
// Go over the sorted text sections.
typedef Unordered_set<Section_id, Section_id_hash> Section_id_set;
Section_id_set processed_input_sections;
for (Text_section_list::const_iterator p = sorted_text_sections.begin();
p != sorted_text_sections.end();
@ -5624,7 +5631,8 @@ Arm_output_section<big_endian>::fix_exidx_coverage(
Relobj* exidx_relobj = exidx_input_section->relobj();
unsigned int exidx_shndx = exidx_input_section->shndx();
Section_id sid(exidx_relobj, exidx_shndx);
if (known_input_sections.find(sid) == known_input_sections.end())
Text_to_exidx_map::const_iterator iter = text_to_exidx_map.find(sid);
if (iter == text_to_exidx_map.end())
{
// This is odd. We have not seen this EXIDX input section before.
// We cannot do fix-up. If we saw a SECTIONS clause in a script,
@ -5679,9 +5687,9 @@ Arm_output_section<big_endian>::fix_exidx_coverage(
{
// Just add back the EXIDX input section.
gold_assert(section_offset_map == NULL);
Output_section::Simple_input_section sis(exidx_relobj, exidx_shndx);
this->add_simple_input_section(sis, exidx_input_section->size(),
exidx_input_section->addralign());
const Output_section::Input_section* pis = iter->second;
gold_assert(pis->is_input_section());
this->add_script_input_section(*pis);
}
processed_input_sections.insert(Section_id(exidx_relobj, exidx_shndx));
@ -5691,7 +5699,7 @@ Arm_output_section<big_endian>::fix_exidx_coverage(
exidx_fixup.add_exidx_cantunwind_as_needed();
// Remove any known EXIDX input sections that are not processed.
for (Simple_input_section_list::const_iterator p = input_sections.begin();
for (Input_section_list::const_iterator p = input_sections.begin();
p != input_sections.end();
++p)
{
@ -10444,6 +10452,7 @@ Target_arm<big_endian>::do_relax(
// If this is the first pass, we need to group input sections into
// stub groups.
bool done_exidx_fixup = false;
typedef typename Stub_table_list::iterator Stub_table_iterator;
if (pass == 1)
{
// Determine the stub group size. The group size is the absolute
@ -10492,13 +10501,27 @@ Target_arm<big_endian>::do_relax(
done_exidx_fixup = true;
}
}
else
{
// If this is not the first pass, addresses and file offsets have
// been reset at this point, set them here.
for (Stub_table_iterator sp = this->stub_tables_.begin();
sp != this->stub_tables_.end();
++sp)
{
Arm_input_section<big_endian>* owner = (*sp)->owner();
off_t off = align_address(owner->original_size(),
(*sp)->addralign());
(*sp)->set_address_and_file_offset(owner->address() + off,
owner->offset() + off);
}
}
// The Cortex-A8 stubs are sensitive to layout of code sections. At the
// beginning of each relaxation pass, just blow away all the stubs.
// Alternatively, we could selectively remove only the stubs and reloc
// information for code sections that have moved since the last pass.
// That would require more book-keeping.
typedef typename Stub_table_list::iterator Stub_table_iterator;
if (this->fix_cortex_a8_)
{
// Clear all Cortex-A8 reloc information.

View File

@ -3046,7 +3046,7 @@ uint64_t
Output_section::get_input_sections(
uint64_t address,
const std::string& fill,
std::list<Simple_input_section>* input_sections)
std::list<Input_section>* input_sections)
{
if (this->checkpoint_ != NULL
&& !this->checkpoint_->input_sections_saved())
@ -3064,12 +3064,8 @@ Output_section::get_input_sections(
p != this->input_sections_.end();
++p)
{
if (p->is_input_section())
input_sections->push_back(Simple_input_section(p->relobj(),
p->shndx()));
else if (p->is_relaxed_input_section())
input_sections->push_back(
Simple_input_section(p->relaxed_input_section()));
if (p->is_input_section() || p->is_relaxed_input_section())
input_sections->push_back(*p);
else
{
uint64_t aligned_address = align_address(address, p->addralign());
@ -3104,13 +3100,16 @@ Output_section::get_input_sections(
return data_size;
}
// Add an simple input section.
// Add a script input section. SIS is an Output_section::Input_section,
// which can be either a plain input section or a special input section like
// a relaxed input section. For a special input section, its size must be
// finalized.
void
Output_section::add_simple_input_section(const Simple_input_section& sis,
off_t data_size,
uint64_t addralign)
Output_section::add_script_input_section(const Input_section& sis)
{
uint64_t data_size = sis.data_size();
uint64_t addralign = sis.addralign();
if (addralign > this->addralign_)
this->addralign_ = addralign;
@ -3121,11 +3120,7 @@ Output_section::add_simple_input_section(const Simple_input_section& sis,
this->set_current_data_size_for_child(aligned_offset_in_section
+ data_size);
Input_section is =
(sis.is_relaxed_input_section()
? Input_section(sis.relaxed_input_section())
: Input_section(sis.relobj(), sis.shndx(), data_size, addralign));
this->input_sections_.push_back(is);
this->input_sections_.push_back(sis);
}
// Save states for relaxation.

View File

@ -2766,263 +2766,6 @@ class Output_section : public Output_data
// The next few calls are for linker script support.
// We need to export the input sections to linker scripts. Previously
// we export a pair of Relobj pointer and section index. We now need to
// handle relaxed input sections as well. So we use this class.
class Simple_input_section
{
private:
static const unsigned int invalid_shndx = static_cast<unsigned int>(-1);
public:
Simple_input_section(Relobj *relobj, unsigned int shndx)
: shndx_(shndx)
{
gold_assert(shndx != invalid_shndx);
this->u_.relobj = relobj;
}
Simple_input_section(Output_relaxed_input_section* section)
: shndx_(invalid_shndx)
{ this->u_.relaxed_input_section = section; }
// Whether this is a relaxed section.
bool
is_relaxed_input_section() const
{ return this->shndx_ == invalid_shndx; }
// Return object of an input section.
Relobj*
relobj() const
{
return ((this->shndx_ != invalid_shndx)
? this->u_.relobj
: this->u_.relaxed_input_section->relobj());
}
// Return index of an input section.
unsigned int
shndx() const
{
return ((this->shndx_ != invalid_shndx)
? this->shndx_
: this->u_.relaxed_input_section->shndx());
}
// Return the Output_relaxed_input_section object of a relaxed section.
Output_relaxed_input_section*
relaxed_input_section() const
{
gold_assert(this->shndx_ == invalid_shndx);
return this->u_.relaxed_input_section;
}
private:
// Pointer to either an Relobj or an Output_relaxed_input_section.
union
{
Relobj* relobj;
Output_relaxed_input_section* relaxed_input_section;
} u_;
// Section index for an non-relaxed section or invalid_shndx for
// a relaxed section.
unsigned int shndx_;
};
// Store the list of input sections for this Output_section into the
// list passed in. This removes the input sections, leaving only
// any Output_section_data elements. This returns the size of those
// Output_section_data elements. ADDRESS is the address of this
// output section. FILL is the fill value to use, in case there are
// any spaces between the remaining Output_section_data elements.
uint64_t
get_input_sections(uint64_t address, const std::string& fill,
std::list<Simple_input_section>*);
// Add a simple input section.
void
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.
void
set_current_data_size(off_t size)
{ this->set_current_data_size_for_child(size); }
// Get the current size of the output section.
off_t
current_data_size() const
{ return this->current_data_size_for_child(); }
// End of linker script support.
// Save states before doing section layout.
// This is used for relaxation.
void
save_states();
// Restore states prior to section layout.
void
restore_states();
// Discard states.
void
discard_states();
// Convert existing input sections to relaxed input sections.
void
convert_input_sections_to_relaxed_sections(
const std::vector<Output_relaxed_input_section*>& sections);
// Find a relaxed input section to an input section in OBJECT
// with index SHNDX. Return NULL if none is found.
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();
// Whether this is a NOLOAD section.
bool
is_noload() const
{ return this->is_noload_; }
// Set NOLOAD flag.
void
set_is_noload()
{ this->is_noload_ = true; }
// Print merge statistics to stderr.
void
print_merge_stats();
protected:
// Return the output section--i.e., the object itself.
Output_section*
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
{
gold_assert(this->out_shndx_ != -1U);
return this->out_shndx_;
}
// Set the output section index.
void
do_set_out_shndx(unsigned int shndx)
{
gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx);
this->out_shndx_ = shndx;
}
// Set the final data size of the Output_section. For a typical
// Output_section, there is nothing to do, but if there are any
// Output_section_data objects we need to set their final addresses
// here.
virtual void
set_final_data_size();
// Reset the address and file offset.
void
do_reset_address_and_file_offset();
// Return true if address and file offset already have reset values. In
// other words, calling reset_address_and_file_offset will not change them.
bool
do_address_and_file_offset_have_reset_values() const;
// Write the data to the file. For a typical Output_section, this
// does nothing: the data is written out by calling Object::Relocate
// on each input object. But if there are any Output_section_data
// objects we do need to write them out here.
virtual void
do_write(Output_file*);
// Return the address alignment--function required by parent class.
uint64_t
do_addralign() const
{ return this->addralign_; }
// Return whether there is a load address.
bool
do_has_load_address() const
{ return this->has_load_address_; }
// Return the load address.
uint64_t
do_load_address() const
{
gold_assert(this->has_load_address_);
return this->load_address_;
}
// Return whether this is an Output_section.
bool
do_is_section() const
{ return true; }
// Return whether this is a section of the specified type.
bool
do_is_section_type(elfcpp::Elf_Word type) const
{ return this->type_ == type; }
// Return whether the specified section flag is set.
bool
do_is_section_flag_set(elfcpp::Elf_Xword flag) const
{ return (this->flags_ & flag) != 0; }
// Set the TLS offset. Called only for SHT_TLS sections.
void
do_set_tls_offset(uint64_t tls_base);
// Return the TLS offset, relative to the base of the TLS segment.
// Valid only for SHT_TLS sections.
uint64_t
do_tls_offset() const
{ return this->tls_offset_; }
// This may be implemented by a child class.
virtual void
do_finalize_name(Layout*)
{ }
// Print to the map file.
virtual void
do_print_to_mapfile(Mapfile*) const;
// Record that this section requires postprocessing after all
// relocations have been applied. This is called by a child class.
void
set_requires_postprocessing()
{
this->requires_postprocessing_ = true;
this->after_input_sections_ = true;
}
// Write all the data of an Output_section into the postprocessing
// buffer.
void
write_to_postprocessing_buffer();
// In some cases we need to keep a list of the input sections
// associated with this output section. We only need the list if we
// might have to change the offsets of the input section within the
@ -3088,13 +2831,29 @@ class Output_section : public Output_data
uint64_t
addralign() const
{
if (!this->is_input_section())
if (this->p2align_ != 0)
return static_cast<uint64_t>(1) << (this->p2align_ - 1);
else if (!this->is_input_section())
return this->u2_.posd->addralign();
return (this->p2align_ == 0
? 0
: static_cast<uint64_t>(1) << (this->p2align_ - 1));
else
return 0;
}
// Set the required alignment, which must be either 0 or a power of 2.
// For input sections that are sub-classes of Output_section_data, a
// alignment of zero means asking the underlying object for alignment.
void
set_addralign(uint64_t addralign)
{
if (addralign == 0)
this->p2align_ = 0;
else
{
gold_assert((addralign & (addralign - 1)) == 0);
this->p2align_ = ffsll(static_cast<long long>(addralign));
}
}
// Return the required size.
off_t
data_size() const;
@ -3294,6 +3053,200 @@ class Output_section : public Output_data
} u2_;
};
// Store the list of input sections for this Output_section into the
// list passed in. This removes the input sections, leaving only
// any Output_section_data elements. This returns the size of those
// Output_section_data elements. ADDRESS is the address of this
// output section. FILL is the fill value to use, in case there are
// any spaces between the remaining Output_section_data elements.
uint64_t
get_input_sections(uint64_t address, const std::string& fill,
std::list<Input_section>*);
// Add a script input section. A script input section can either be
// a plain input section or a sub-class of Output_section_data.
void
add_script_input_section(const Input_section& input_section);
// Set the current size of the output section.
void
set_current_data_size(off_t size)
{ this->set_current_data_size_for_child(size); }
// Get the current size of the output section.
off_t
current_data_size() const
{ return this->current_data_size_for_child(); }
// End of linker script support.
// Save states before doing section layout.
// This is used for relaxation.
void
save_states();
// Restore states prior to section layout.
void
restore_states();
// Discard states.
void
discard_states();
// Convert existing input sections to relaxed input sections.
void
convert_input_sections_to_relaxed_sections(
const std::vector<Output_relaxed_input_section*>& sections);
// Find a relaxed input section to an input section in OBJECT
// with index SHNDX. Return NULL if none is found.
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();
// Whether this is a NOLOAD section.
bool
is_noload() const
{ return this->is_noload_; }
// Set NOLOAD flag.
void
set_is_noload()
{ this->is_noload_ = true; }
// Print merge statistics to stderr.
void
print_merge_stats();
protected:
// Return the output section--i.e., the object itself.
Output_section*
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
{
gold_assert(this->out_shndx_ != -1U);
return this->out_shndx_;
}
// Set the output section index.
void
do_set_out_shndx(unsigned int shndx)
{
gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx);
this->out_shndx_ = shndx;
}
// Set the final data size of the Output_section. For a typical
// Output_section, there is nothing to do, but if there are any
// Output_section_data objects we need to set their final addresses
// here.
virtual void
set_final_data_size();
// Reset the address and file offset.
void
do_reset_address_and_file_offset();
// Return true if address and file offset already have reset values. In
// other words, calling reset_address_and_file_offset will not change them.
bool
do_address_and_file_offset_have_reset_values() const;
// Write the data to the file. For a typical Output_section, this
// does nothing: the data is written out by calling Object::Relocate
// on each input object. But if there are any Output_section_data
// objects we do need to write them out here.
virtual void
do_write(Output_file*);
// Return the address alignment--function required by parent class.
uint64_t
do_addralign() const
{ return this->addralign_; }
// Return whether there is a load address.
bool
do_has_load_address() const
{ return this->has_load_address_; }
// Return the load address.
uint64_t
do_load_address() const
{
gold_assert(this->has_load_address_);
return this->load_address_;
}
// Return whether this is an Output_section.
bool
do_is_section() const
{ return true; }
// Return whether this is a section of the specified type.
bool
do_is_section_type(elfcpp::Elf_Word type) const
{ return this->type_ == type; }
// Return whether the specified section flag is set.
bool
do_is_section_flag_set(elfcpp::Elf_Xword flag) const
{ return (this->flags_ & flag) != 0; }
// Set the TLS offset. Called only for SHT_TLS sections.
void
do_set_tls_offset(uint64_t tls_base);
// Return the TLS offset, relative to the base of the TLS segment.
// Valid only for SHT_TLS sections.
uint64_t
do_tls_offset() const
{ return this->tls_offset_; }
// This may be implemented by a child class.
virtual void
do_finalize_name(Layout*)
{ }
// Print to the map file.
virtual void
do_print_to_mapfile(Mapfile*) const;
// Record that this section requires postprocessing after all
// relocations have been applied. This is called by a child class.
void
set_requires_postprocessing()
{
this->requires_postprocessing_ = true;
this->after_input_sections_ = true;
}
// Write all the data of an Output_section into the postprocessing
// buffer.
void
write_to_postprocessing_buffer();
typedef std::vector<Input_section> Input_section_list;
// Allow a child class to access the input sections.

View File

@ -546,7 +546,7 @@ class Output_section_element
{
public:
// A list of input sections.
typedef std::list<Output_section::Simple_input_section> Input_section_list;
typedef std::list<Output_section::Input_section> Input_section_list;
Output_section_element()
{ }
@ -1195,13 +1195,13 @@ Output_section_element_input::match_name(const char* file_name,
class Input_section_info
{
public:
Input_section_info(const Output_section::Simple_input_section& input_section)
Input_section_info(const Output_section::Input_section& input_section)
: input_section_(input_section), section_name_(),
size_(0), addralign_(1)
{ }
// Return the simple input section.
const Output_section::Simple_input_section&
const Output_section::Input_section&
input_section() const
{ return this->input_section_; }
@ -1247,7 +1247,7 @@ class Input_section_info
private:
// Input section, can be a relaxed section.
Output_section::Simple_input_section input_section_;
Output_section::Input_section input_section_;
// Name of the section.
std::string section_name_;
// Section size.
@ -1418,9 +1418,20 @@ Output_section_element_input::set_section_addresses(
p != matching_sections[i].end();
++p)
{
uint64_t this_subalign = p->addralign();
// Override the original address alignment if SUBALIGN is specified
// and is greater than the original alignment. We need to make a
// copy of the input section to modify the alignment.
Output_section::Input_section sis(p->input_section());
uint64_t this_subalign = sis.addralign();
if (!sis.is_input_section())
sis.output_section_data()->finalize_data_size();
uint64_t data_size = sis.data_size();
if (this_subalign < subalign)
this_subalign = subalign;
{
this_subalign = subalign;
sis.set_addralign(subalign);
}
uint64_t address = align_address(dot, this_subalign);
@ -1434,11 +1445,8 @@ Output_section_element_input::set_section_addresses(
layout->new_output_section_data_from_script(posd);
}
output_section->add_simple_input_section(p->input_section(),
p->size(),
this_subalign);
dot = address + p->size();
output_section->add_script_input_section(sis);
dot = address + data_size;
}
}
@ -2381,7 +2389,7 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
uint64_t*,
uint64_t* load_address)
{
typedef std::list<Output_section::Simple_input_section> Input_section_list;
typedef std::list<Output_section::Input_section> Input_section_list;
bool have_load_address = *load_address != *dot_value;
@ -2403,25 +2411,12 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
p != input_sections.end();
++p)
{
uint64_t addralign;
uint64_t size;
// We know we are single-threaded, so it is OK to lock the
// object.
{
const Task* task = reinterpret_cast<const Task*>(-1);
Task_lock_obj<Object> tl(task, p->relobj());
addralign = p->relobj()->section_addralign(p->shndx());
if (p->is_relaxed_input_section())
// We use current data size because relxed section sizes may not
// have finalized yet.
size = p->relaxed_input_section()->current_data_size();
else
size = p->relobj()->section_size(p->shndx());
}
uint64_t addralign = p->addralign();
if (!p->is_input_section())
p->output_section_data()->finalize_data_size();
uint64_t size = p->data_size();
address = align_address(address, addralign);
this->os_->add_simple_input_section(*p, size, addralign);
this->os_->add_script_input_section(*p);
address += size;
}