diff options
author | Cary Coutant <ccoutant@google.com> | 2011-08-27 01:28:18 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2011-08-27 01:28:18 +0000 |
commit | 8ea8cd50dda899e110495d5d4251706bc7c8bb1e (patch) | |
tree | e835bae6def9161cfce1098985b124aef2ecf4e6 /gold/layout.cc | |
parent | 53c8030fecbe40b6a676dd52b89e03ef563c2f0c (diff) | |
download | binutils-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.cc | 28 |
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 |