Fix SIZEOF_HEADERS in gold.
Gold undercounts the number of program headers it's going to add when initially evaluating the SIZEOF_HEADERS expression. As a result, scripts that use it end up skipping a page unnecessarily when the starting address is too low. The undercounting is because it doesn't count the PT_INTERP segment. Then, when finalizing symbols, gold overcounts the program headers: all segments have already been created, but we still count the headers we expected to add from the script. This patch fixes both problems. gold/ * script-sections.cc (Script_sections::Script_sections): Initialize segments_created_. (Script_sections::create_note_and_tls_segments): Set flag when segments are created. (Script_sections::expected_segment_count): Count PT_INTERP. (Script_sections::attach_sections_using_phdrs_clause): Set flag when segments are created. * script-sections.h (Script_sections::segments_created_): New data member.
This commit is contained in:
parent
374082dfab
commit
8086551f52
3 changed files with 35 additions and 3 deletions
|
@ -1,3 +1,15 @@
|
|||
2015-06-03 Cary Coutant <cary@google.com>
|
||||
|
||||
* script-sections.cc (Script_sections::Script_sections): Initialize
|
||||
segments_created_.
|
||||
(Script_sections::create_note_and_tls_segments): Set flag when
|
||||
segments are created.
|
||||
(Script_sections::expected_segment_count): Count PT_INTERP.
|
||||
(Script_sections::attach_sections_using_phdrs_clause): Set flag when
|
||||
segments are created.
|
||||
* script-sections.h (Script_sections::segments_created_): New data
|
||||
member.
|
||||
|
||||
2015-06-03 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/15370
|
||||
|
|
|
@ -3200,7 +3200,8 @@ Script_sections::Script_sections()
|
|||
data_segment_align_start_(),
|
||||
saw_data_segment_align_(false),
|
||||
saw_relro_end_(false),
|
||||
saw_segment_start_expression_(false)
|
||||
saw_segment_start_expression_(false),
|
||||
segments_created_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -4007,8 +4008,8 @@ Script_sections::create_note_and_tls_segments(
|
|||
saw_tls = true;
|
||||
}
|
||||
|
||||
// If we are making a shared library, and we see a section named
|
||||
// .interp then put the .interp section in a PT_INTERP segment.
|
||||
// If we see a section named .interp then put the .interp section
|
||||
// in a PT_INTERP segment.
|
||||
// This is for GNU ld compatibility.
|
||||
if (strcmp((*p)->name(), ".interp") == 0)
|
||||
{
|
||||
|
@ -4019,6 +4020,8 @@ Script_sections::create_note_and_tls_segments(
|
|||
oseg->add_output_section_to_nonload(*p, seg_flags);
|
||||
}
|
||||
}
|
||||
|
||||
this->segments_created_ = true;
|
||||
}
|
||||
|
||||
// Add a program header. The PHDRS clause is syntactically distinct
|
||||
|
@ -4046,6 +4049,10 @@ Script_sections::add_phdr(const char* name, size_t namelen, unsigned int type,
|
|||
size_t
|
||||
Script_sections::expected_segment_count(const Layout* layout) const
|
||||
{
|
||||
// If we've already created the segments, we won't be adding any more.
|
||||
if (this->segments_created_)
|
||||
return 0;
|
||||
|
||||
if (this->saw_phdrs_clause())
|
||||
return this->phdrs_elements_->size();
|
||||
|
||||
|
@ -4057,6 +4064,7 @@ Script_sections::expected_segment_count(const Layout* layout) const
|
|||
|
||||
bool saw_note = false;
|
||||
bool saw_tls = false;
|
||||
bool saw_interp = false;
|
||||
for (Layout::Section_list::const_iterator p = sections.begin();
|
||||
p != sections.end();
|
||||
++p)
|
||||
|
@ -4080,6 +4088,15 @@ Script_sections::expected_segment_count(const Layout* layout) const
|
|||
saw_tls = true;
|
||||
}
|
||||
}
|
||||
else if (strcmp((*p)->name(), ".interp") == 0)
|
||||
{
|
||||
// There can only be one PT_INTERP segment.
|
||||
if (!saw_interp)
|
||||
{
|
||||
++ret;
|
||||
saw_interp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -4108,6 +4125,7 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
|
|||
p != this->phdrs_elements_->end();
|
||||
++p)
|
||||
name_to_segment[(*p)->name()] = (*p)->create_segment(layout);
|
||||
this->segments_created_ = true;
|
||||
|
||||
// Walk through the output sections and attach them to segments.
|
||||
// Output sections in the script which do not list segments are
|
||||
|
|
|
@ -319,6 +319,8 @@ class Script_sections
|
|||
bool saw_relro_end_;
|
||||
// Whether we have seen SEGMENT_START.
|
||||
bool saw_segment_start_expression_;
|
||||
// Whether we have created all necessary segments.
|
||||
bool segments_created_;
|
||||
};
|
||||
|
||||
// Attributes for memory regions.
|
||||
|
|
Loading…
Reference in a new issue