* layout.cc (Layout::set_segment_offsets): Align the file offset

to the segment aligment for -N or -n with no load segment.
	* output.cc (Output_segment::add_output_section): Don't crash if
	the first section is a TLS section.
	(Output_segment::set_section_list_addresses): Print an error
	message if the address moves backward in a linker script.
	* script-sections.cc
	(Output_section_element_input::set_section_addresses): Don't
	increase *dot_value for a SHF_TLS/SHT_NOBITS section.
	(Orphan_output_section::set_section_addresses): Likewise.
This commit is contained in:
Ian Lance Taylor 2009-10-16 05:00:29 +00:00
parent 6b3159bb46
commit 661be1e21e
4 changed files with 99 additions and 36 deletions

View File

@ -1,3 +1,16 @@
2009-10-15 Ian Lance Taylor <iant@google.com>
* layout.cc (Layout::set_segment_offsets): Align the file offset
to the segment aligment for -N or -n with no load segment.
* output.cc (Output_segment::add_output_section): Don't crash if
the first section is a TLS section.
(Output_segment::set_section_list_addresses): Print an error
message if the address moves backward in a linker script.
* script-sections.cc
(Output_section_element_input::set_section_addresses): Don't
increase *dot_value for a SHF_TLS/SHT_NOBITS section.
(Orphan_output_section::set_section_addresses): Likewise.
2009-10-15 Doug Kwan <dougkwan@google.com>
* layout.cc (Layout::finish_dynamic_section): Generate tags

View File

@ -2237,6 +2237,19 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
if (!parameters->options().nmagic()
&& !parameters->options().omagic())
off = align_file_offset(off, addr, abi_pagesize);
else if (load_seg == NULL)
{
// This is -N or -n with a section script which prevents
// us from using a load segment. We need to ensure that
// the file offset is aligned to the alignment of the
// segment. This is because the linker script
// implicitly assumed a zero offset. If we don't align
// here, then the alignment of the sections in the
// linker script may not match the alignment of the
// sections in the set_section_addresses call below,
// causing an error about dot moving backward.
off = align_address(off, (*p)->maximum_alignment());
}
unsigned int shndx_hold = *pshndx;
uint64_t new_addr = (*p)->set_section_addresses(this, false, addr,

View File

@ -3100,36 +3100,41 @@ Output_segment::add_output_section(Output_section* os,
&& (os->flags() & elfcpp::SHF_TLS) != 0)
{
pdl = &this->output_data_;
bool nobits = os->type() == elfcpp::SHT_NOBITS;
bool sawtls = false;
Output_segment::Output_data_list::iterator p = pdl->end();
do
if (!pdl->empty())
{
--p;
bool insert;
if ((*p)->is_section_flag_set(elfcpp::SHF_TLS))
bool nobits = os->type() == elfcpp::SHT_NOBITS;
bool sawtls = false;
Output_segment::Output_data_list::iterator p = pdl->end();
gold_assert(p != pdl->begin());
do
{
sawtls = true;
// Put a NOBITS section after the first TLS section.
// Put a PROGBITS section after the first TLS/PROGBITS
// section.
insert = nobits || !(*p)->is_section_type(elfcpp::SHT_NOBITS);
}
else
{
// If we've gone past the TLS sections, but we've seen a
// TLS section, then we need to insert this section now.
insert = sawtls;
}
--p;
bool insert;
if ((*p)->is_section_flag_set(elfcpp::SHF_TLS))
{
sawtls = true;
// Put a NOBITS section after the first TLS section.
// Put a PROGBITS section after the first
// TLS/PROGBITS section.
insert = nobits || !(*p)->is_section_type(elfcpp::SHT_NOBITS);
}
else
{
// If we've gone past the TLS sections, but we've
// seen a TLS section, then we need to insert this
// section now.
insert = sawtls;
}
if (insert)
{
++p;
pdl->insert(p, os);
return;
if (insert)
{
++p;
pdl->insert(p, os);
return;
}
}
while (p != pdl->begin());
}
while (p != pdl->begin());
// There are no TLS sections yet; put this one at the requested
// location in the section list.
@ -3489,8 +3494,26 @@ Output_segment::set_section_list_addresses(const Layout* layout, bool reset,
{
// The script may have inserted a skip forward, but it
// better not have moved backward.
gold_assert((*p)->address() >= addr + (off - startoff));
off += (*p)->address() - (addr + (off - startoff));
if ((*p)->address() >= addr + (off - startoff))
off += (*p)->address() - (addr + (off - startoff));
else
{
if (!layout->script_options()->saw_sections_clause())
gold_unreachable();
else
{
Output_section* os = (*p)->output_section();
if (os == NULL)
gold_error(_("dot moves backward in linker script "
"from 0x%llx to 0x%llx"),
addr + (off - startoff), (*p)->address());
else
gold_error(_("address of section '%s' moves backward "
"from 0x%llx to 0x%llx"),
os->name(), addr + (off - startoff),
(*p)->address());
}
}
(*p)->set_file_offset(off);
(*p)->finalize_data_size();
}

View File

@ -1372,6 +1372,7 @@ Output_section_element_input::set_section_addresses(
// sections are otherwise equal. Add each input section to the
// output section.
uint64_t dot = *dot_value;
for (size_t i = 0; i < input_pattern_count; ++i)
{
if (matching_sections[i].empty())
@ -1396,12 +1397,12 @@ Output_section_element_input::set_section_addresses(
if (this_subalign < subalign)
this_subalign = subalign;
uint64_t address = align_address(*dot_value, this_subalign);
uint64_t address = align_address(dot, this_subalign);
if (address > *dot_value && !fill->empty())
if (address > dot && !fill->empty())
{
section_size_type length =
convert_to_section_size_type(address - *dot_value);
convert_to_section_size_type(address - dot);
std::string this_fill = this->get_fill_string(fill, length);
Output_section_data* posd = new Output_data_const(this_fill, 0);
output_section->add_output_section_data(posd);
@ -1412,10 +1413,17 @@ Output_section_element_input::set_section_addresses(
p->size(),
this_subalign);
*dot_value = address + p->size();
dot = address + p->size();
}
}
// An SHF_TLS/SHT_NOBITS section does not take up any
// address space.
if (output_section == NULL
|| (output_section->flags() & elfcpp::SHF_TLS) == 0
|| output_section->type() != elfcpp::SHT_NOBITS)
*dot_value = dot;
this->final_dot_value_ = *dot_value;
this->final_dot_section_ = *dot_section;
}
@ -2311,12 +2319,18 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
address += size;
}
if (!have_load_address)
*load_address = address;
else
*load_address += address - *dot_value;
// An SHF_TLS/SHT_NOBITS section does not take up any address space.
if (this->os_ == NULL
|| (this->os_->flags() & elfcpp::SHF_TLS) == 0
|| this->os_->type() != elfcpp::SHT_NOBITS)
{
if (!have_load_address)
*load_address = address;
else
*load_address += address - *dot_value;
*dot_value = address;
*dot_value = address;
}
}
// Get the list of segments to use for an allocated section when using