* layout.cc (Free_list::allocate): Provide guarantee of minimum

remaining hole size when allocating.
	(Layout::make_output_section): Set fill methods for debug sections.
	* layout.h (Free_list::Free_list_node): Move from private to
	public.
	(Free_list::set_min_hole_size): New function.
	(Free_list::begin, Free_list::end): New functions.
	(Free_list::min_hole_): New data member.
	* output.cc: Include dwarf.h.
	(Output_fill_debug_info::do_minimum_hole_size): New function.
	(Output_fill_debug_info::do_write): New function.
	(Output_fill_debug_line::do_minimum_hole_size): New function.
	(Output_fill_debug_line::do_write): New function.
	(Output_section::Output_section): Initialize new data member.
	(Output_section::set_final_data_size): Ensure patch space is larger
	than minimum hole size.
	(Output_section::do_write): Fill holes in debug sections.
	* output.h (Output_fill): New class.
	(Output_fill_debug_info): New class.
	(Output_fill_debug_line): New class.
	(Output_section::set_free_space_fill): New function.
	(Output_section::free_space_fill_): New data member.
	* testsuite/Makefile.am (incremental_test_3): Add
	--incremental-patch option.
	(incremental_test_4): Likewise.
	(incremental_test_5): Likewise.
	(incremental_test_6): Likewise.
	(incremental_copy_test): Likewise.
	(incremental_common_test_1): Likewise.
	* testsuite/Makefile.in: Regenerate.
This commit is contained in:
Cary Coutant
2011-08-27 01:28:18 +00:00
parent 53c8030fec
commit 8ea8cd50dd
7 changed files with 382 additions and 38 deletions

View File

@@ -162,6 +162,11 @@ Free_list::allocate(off_t len, uint64_t align, off_t minoff)
++Free_list::num_allocates;
// We usually want to drop free chunks smaller than 4 bytes.
// If we need to guarantee a minimum hole size, though, we need
// to keep track of all free chunks.
const int fuzz = this->min_hole_ > 0 ? 0 : 3;
for (Iterator p = this->list_.begin(); p != this->list_.end(); ++p)
{
++Free_list::num_allocate_visits;
@@ -173,13 +178,13 @@ Free_list::allocate(off_t len, uint64_t align, off_t minoff)
this->length_ = end;
p->end_ = end;
}
if (end <= p->end_)
if (end == p->end_ || (end <= p->end_ - this->min_hole_))
{
if (p->start_ + 3 >= start && p->end_ <= end + 3)
if (p->start_ + fuzz >= start && p->end_ <= end + fuzz)
this->list_.erase(p);
else if (p->start_ + 3 >= start)
else if (p->start_ + fuzz >= start)
p->start_ = end;
else if (p->end_ <= end + 3)
else if (p->end_ <= end + fuzz)
p->end_ = start;
else
{
@@ -1440,7 +1445,20 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
&& strcmp(name, ".ctors") != 0
&& strcmp(name, ".dtors") != 0
&& strcmp(name, ".jcr") != 0)
os->set_is_patch_space_allowed();
{
os->set_is_patch_space_allowed();
// Certain sections require "holes" to be filled with
// specific fill patterns. These fill patterns may have
// a minimum size, so we must prevent allocations from the
// free list that leave a hole smaller than the minimum.
if (strcmp(name, ".debug_info") == 0)
os->set_free_space_fill(new Output_fill_debug_info(false));
else if (strcmp(name, ".debug_types") == 0)
os->set_free_space_fill(new Output_fill_debug_info(true));
else if (strcmp(name, ".debug_line") == 0)
os->set_free_space_fill(new Output_fill_debug_line());
}
// If we have already attached the sections to segments, then we
// need to attach this one now. This happens for sections created