summaryrefslogtreecommitdiff
path: root/gold/layout.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2011-08-27 01:28:18 +0000
committerCary Coutant <ccoutant@google.com>2011-08-27 01:28:18 +0000
commit8ea8cd50dda899e110495d5d4251706bc7c8bb1e (patch)
treee835bae6def9161cfce1098985b124aef2ecf4e6 /gold/layout.cc
parent53c8030fecbe40b6a676dd52b89e03ef563c2f0c (diff)
downloadbinutils-gdb-8ea8cd50dda899e110495d5d4251706bc7c8bb1e.tar.gz
* 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.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r--gold/layout.cc28
1 files changed, 23 insertions, 5 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index 44c2e183e82..afb5b6af041 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -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