OLD | NEW |
(Empty) | |
| 1 commit ac423761af22f7858a1413cda5df3e1d5e88d4e4 |
| 2 Author: Gergely Nagy <ngg@tresorit.com> |
| 3 Date: Fri Oct 21 11:08:20 2016 -0700 |
| 4 |
| 5 Fix PR 17704. |
| 6 |
| 7 This fix keeps the section with the highest alignment when folding sections
with ICF. |
| 8 |
| 9 PR gold/17704 |
| 10 * icf.cc (match_sections): Add new parameter section_addraligns. |
| 11 Check section alignment and keep the section with the strictest |
| 12 alignment. |
| 13 (find_identical_sections): New local variable section_addraligns. |
| 14 Store each section's alignment. |
| 15 * testsuite/pr17704a_test.s: New file. |
| 16 * testsuite/Makefile.am (pr17704a_test): New test. |
| 17 * testsuite/Makefile.in: Regenerate. |
| 18 |
| 19 diff --git a/gold/icf.cc b/gold/icf.cc |
| 20 index dce0b8b3e2..c09c746ae1 100644 |
| 21 --- a/gold/icf.cc |
| 22 +++ b/gold/icf.cc |
| 23 @@ -590,6 +590,7 @@ match_sections(unsigned int iteration_num, |
| 24 std::vector<unsigned int>* num_tracked_relocs, |
| 25 std::vector<unsigned int>* kept_section_id, |
| 26 const std::vector<Section_id>& id_section, |
| 27 + const std::vector<uint64_t>& section_addraligns, |
| 28 std::vector<bool>* is_secn_or_group_unique, |
| 29 std::vector<std::string>* section_contents) |
| 30 { |
| 31 @@ -630,13 +631,7 @@ match_sections(unsigned int iteration_num, |
| 32 { |
| 33 if ((*kept_section_id)[i] != i) |
| 34 { |
| 35 - // This section is already folded into something. See |
| 36 - // if it should point to a different kept section. |
| 37 - unsigned int kept_section = (*kept_section_id)[i]; |
| 38 - if (kept_section != (*kept_section_id)[kept_section]) |
| 39 - { |
| 40 - (*kept_section_id)[i] = (*kept_section_id)[kept_section]; |
| 41 - } |
| 42 + // This section is already folded into something. |
| 43 continue; |
| 44 } |
| 45 this_secn_contents = get_section_contents(false, secn, i, NULL, |
| 46 @@ -671,7 +666,25 @@ match_sections(unsigned int iteration_num, |
| 47 this_secn_contents.c_str(), |
| 48 this_secn_contents.length()) != 0) |
| 49 continue; |
| 50 - (*kept_section_id)[i] = kept_section; |
| 51 + |
| 52 + // Check section alignment here. |
| 53 + // The section with the larger alignment requirement |
| 54 + // should be kept. We assume alignment can only be |
| 55 + // zero or postive integral powers of two. |
| 56 + uint64_t align_i = section_addraligns[i]; |
| 57 + uint64_t align_kept = section_addraligns[kept_section]; |
| 58 + if (align_i <= align_kept) |
| 59 + { |
| 60 + (*kept_section_id)[i] = kept_section; |
| 61 + } |
| 62 + else |
| 63 + { |
| 64 + (*kept_section_id)[kept_section] = i; |
| 65 + it->second = i; |
| 66 + full_section_contents[kept_section].swap( |
| 67 + full_section_contents[i]); |
| 68 + } |
| 69 + |
| 70 converged = false; |
| 71 break; |
| 72 } |
| 73 @@ -688,6 +701,26 @@ match_sections(unsigned int iteration_num, |
| 74 (*is_secn_or_group_unique)[i] = true; |
| 75 } |
| 76 |
| 77 + // If a section was folded into another section that was later folded |
| 78 + // again then the former has to be updated. |
| 79 + for (unsigned int i = 0; i < id_section.size(); i++) |
| 80 + { |
| 81 + // Find the end of the folding chain |
| 82 + unsigned int kept = i; |
| 83 + while ((*kept_section_id)[kept] != kept) |
| 84 + { |
| 85 + kept = (*kept_section_id)[kept]; |
| 86 + } |
| 87 + // Update every element of the chain |
| 88 + unsigned int current = i; |
| 89 + while ((*kept_section_id)[current] != kept) |
| 90 + { |
| 91 + unsigned int next = (*kept_section_id)[current]; |
| 92 + (*kept_section_id)[current] = kept; |
| 93 + current = next; |
| 94 + } |
| 95 + } |
| 96 + |
| 97 return converged; |
| 98 } |
| 99 |
| 100 @@ -719,6 +752,7 @@ Icf::find_identical_sections(const Input_objects* input_obje
cts, |
| 101 { |
| 102 unsigned int section_num = 0; |
| 103 std::vector<unsigned int> num_tracked_relocs; |
| 104 + std::vector<uint64_t> section_addraligns; |
| 105 std::vector<bool> is_secn_or_group_unique; |
| 106 std::vector<std::string> section_contents; |
| 107 const Target& target = parameters->target(); |
| 108 @@ -759,6 +793,7 @@ Icf::find_identical_sections(const Input_objects* input_obje
cts, |
| 109 this->section_id_[Section_id(*p, i)] = section_num; |
| 110 this->kept_section_id_.push_back(section_num); |
| 111 num_tracked_relocs.push_back(0); |
| 112 + section_addraligns.push_back((*p)->section_addralign(i)); |
| 113 is_secn_or_group_unique.push_back(false); |
| 114 section_contents.push_back(""); |
| 115 section_num++; |
| 116 @@ -779,8 +814,8 @@ Icf::find_identical_sections(const Input_objects* input_obje
cts, |
| 117 num_iterations++; |
| 118 converged = match_sections(num_iterations, symtab, |
| 119 &num_tracked_relocs, &this->kept_section_id_, |
| 120 - this->id_section_, &is_secn_or_group_unique, |
| 121 - §ion_contents); |
| 122 + this->id_section_, section_addraligns, |
| 123 + &is_secn_or_group_unique, §ion_contents); |
| 124 } |
| 125 |
| 126 if (parameters->options().print_icf_sections()) |
OLD | NEW |