mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-10 01:23:17 +00:00
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:
@@ -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>
|
2015-06-03 Cary Coutant <ccoutant@gmail.com>
|
||||||
|
|
||||||
PR gold/15370
|
PR gold/15370
|
||||||
|
|||||||
@@ -3200,7 +3200,8 @@ Script_sections::Script_sections()
|
|||||||
data_segment_align_start_(),
|
data_segment_align_start_(),
|
||||||
saw_data_segment_align_(false),
|
saw_data_segment_align_(false),
|
||||||
saw_relro_end_(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;
|
saw_tls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are making a shared library, and we see a section named
|
// If we see a section named .interp then put the .interp section
|
||||||
// .interp then put the .interp section in a PT_INTERP segment.
|
// in a PT_INTERP segment.
|
||||||
// This is for GNU ld compatibility.
|
// This is for GNU ld compatibility.
|
||||||
if (strcmp((*p)->name(), ".interp") == 0)
|
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);
|
oseg->add_output_section_to_nonload(*p, seg_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->segments_created_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a program header. The PHDRS clause is syntactically distinct
|
// 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
|
size_t
|
||||||
Script_sections::expected_segment_count(const Layout* layout) const
|
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())
|
if (this->saw_phdrs_clause())
|
||||||
return this->phdrs_elements_->size();
|
return this->phdrs_elements_->size();
|
||||||
|
|
||||||
@@ -4057,6 +4064,7 @@ Script_sections::expected_segment_count(const Layout* layout) const
|
|||||||
|
|
||||||
bool saw_note = false;
|
bool saw_note = false;
|
||||||
bool saw_tls = false;
|
bool saw_tls = false;
|
||||||
|
bool saw_interp = false;
|
||||||
for (Layout::Section_list::const_iterator p = sections.begin();
|
for (Layout::Section_list::const_iterator p = sections.begin();
|
||||||
p != sections.end();
|
p != sections.end();
|
||||||
++p)
|
++p)
|
||||||
@@ -4080,6 +4088,15 @@ Script_sections::expected_segment_count(const Layout* layout) const
|
|||||||
saw_tls = true;
|
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;
|
return ret;
|
||||||
@@ -4108,6 +4125,7 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
|
|||||||
p != this->phdrs_elements_->end();
|
p != this->phdrs_elements_->end();
|
||||||
++p)
|
++p)
|
||||||
name_to_segment[(*p)->name()] = (*p)->create_segment(layout);
|
name_to_segment[(*p)->name()] = (*p)->create_segment(layout);
|
||||||
|
this->segments_created_ = true;
|
||||||
|
|
||||||
// Walk through the output sections and attach them to segments.
|
// Walk through the output sections and attach them to segments.
|
||||||
// Output sections in the script which do not list segments are
|
// Output sections in the script which do not list segments are
|
||||||
|
|||||||
@@ -319,6 +319,8 @@ class Script_sections
|
|||||||
bool saw_relro_end_;
|
bool saw_relro_end_;
|
||||||
// Whether we have seen SEGMENT_START.
|
// Whether we have seen SEGMENT_START.
|
||||||
bool saw_segment_start_expression_;
|
bool saw_segment_start_expression_;
|
||||||
|
// Whether we have created all necessary segments.
|
||||||
|
bool segments_created_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Attributes for memory regions.
|
// Attributes for memory regions.
|
||||||
|
|||||||
Reference in New Issue
Block a user