mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
* 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:
parent
6b3159bb46
commit
661be1e21e
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user