OLD | NEW |
(Empty) | |
| 1 commit d114b830426300f80302ca03ff4322942f63c615 |
| 2 Author: Roland McGrath <mcgrathr@chromium.org> |
| 3 Date: Thu May 5 13:12:40 2016 -0700 |
| 4 |
| 5 2016-02-05 Sriraman Tallam <tmsriram@google.com> |
| 6 |
| 7 PR gold/19047 |
| 8 * icf.cc (get_rel_addend): New function. |
| 9 (get_section_contents): Move merge section addend computation to a |
| 10 new function. Ignore negative values for SHT_REL and SHT_RELA addends. |
| 11 Fix bug to not read past the length of the section. |
| 12 |
| 13 Fix bug related to addend computation for MERGE sections. |
| 14 |
| 15 (cherry picked from commit 84d543b7ed93bf6511cdf45791f4f0b717dfb718) |
| 16 |
| 17 diff --git a/gold/ChangeLog b/gold/ChangeLog |
| 18 index 92b26ba..ec8dacb 100644 |
| 19 --- a/gold/ChangeLog |
| 20 +++ b/gold/ChangeLog |
| 21 @@ -1,3 +1,11 @@ |
| 22 +2016-02-05 Sriraman Tallam <tmsriram@google.com> |
| 23 + |
| 24 + PR gold/19047 |
| 25 + * icf.cc (get_rel_addend): New function. |
| 26 + (get_section_contents): Move merge section addend computation to a |
| 27 + new function. Ignore negative values for SHT_REL and SHT_RELA addends. |
| 28 + Fix bug to not read past the length of the section. |
| 29 + |
| 30 2015-12-17 Peter Collingbourne <pcc@google.com> |
| 31 |
| 32 PR gold/18780 |
| 33 diff --git a/gold/icf.cc b/gold/icf.cc |
| 34 index 96b7f2d..663d579 100644 |
| 35 --- a/gold/icf.cc |
| 36 +++ b/gold/icf.cc |
| 37 @@ -213,6 +213,45 @@ preprocess_for_unique_sections(const std::vector<Section_id
>& id_section, |
| 38 } |
| 39 } |
| 40 |
| 41 +// For SHF_MERGE sections that use REL relocations, the addend is stored in |
| 42 +// the text section at the relocation offset. Read the addend value given |
| 43 +// the pointer to the addend in the text section and the addend size. |
| 44 +// Update the addend value if a valid addend is found. |
| 45 +// Parameters: |
| 46 +// RELOC_ADDEND_PTR : Pointer to the addend in the text section. |
| 47 +// ADDEND_SIZE : The size of the addend. |
| 48 +// RELOC_ADDEND_VALUE : Pointer to the addend that is updated. |
| 49 + |
| 50 +inline void |
| 51 +get_rel_addend(const unsigned char* reloc_addend_ptr, |
| 52 + const unsigned int addend_size, |
| 53 + uint64_t* reloc_addend_value) |
| 54 +{ |
| 55 + switch (addend_size) |
| 56 + { |
| 57 + case 0: |
| 58 + break; |
| 59 + case 1: |
| 60 + *reloc_addend_value = |
| 61 + read_from_pointer<8>(reloc_addend_ptr); |
| 62 + break; |
| 63 + case 2: |
| 64 + *reloc_addend_value = |
| 65 + read_from_pointer<16>(reloc_addend_ptr); |
| 66 + break; |
| 67 + case 4: |
| 68 + *reloc_addend_value = |
| 69 + read_from_pointer<32>(reloc_addend_ptr); |
| 70 + break; |
| 71 + case 8: |
| 72 + *reloc_addend_value = |
| 73 + read_from_pointer<64>(reloc_addend_ptr); |
| 74 + break; |
| 75 + default: |
| 76 + gold_unreachable(); |
| 77 + } |
| 78 +} |
| 79 + |
| 80 // This returns the buffer containing the section's contents, both |
| 81 // text and relocs. Relocs are differentiated as those pointing to |
| 82 // sections that could be folded and those that cannot. Only relocs |
| 83 @@ -397,58 +436,36 @@ get_section_contents(bool first_iteration, |
| 84 uint64_t entsize = |
| 85 (it_v->first)->section_entsize(it_v->second); |
| 86 long long offset = it_a->first; |
| 87 - |
| 88 - unsigned long long addend = it_a->second; |
| 89 - // Ignoring the addend when it is a negative value. See the |
| 90 - // comments in Merged_symbol_value::Value in object.h. |
| 91 - if (addend < 0xffffff00) |
| 92 - offset = offset + addend; |
| 93 - |
| 94 - // For SHT_REL relocation sections, the addend is stored in th
e |
| 95 - // text section at the relocation offset. |
| 96 - uint64_t reloc_addend_value = 0; |
| 97 + // Handle SHT_RELA and SHT_REL addends, only one of these |
| 98 + // addends exists. |
| 99 + // Get the SHT_RELA addend. For RELA relocations, we have |
| 100 + // the addend from the relocation. |
| 101 + uint64_t reloc_addend_value = it_a->second; |
| 102 + |
| 103 + // Handle SHT_REL addends. |
| 104 + // For REL relocations, we need to fetch the addend from the |
| 105 + // section contents. |
| 106 const unsigned char* reloc_addend_ptr = |
| 107 contents + static_cast<unsigned long long>(*it_o); |
| 108 - switch(*it_addend_size) |
| 109 - { |
| 110 - case 0: |
| 111 - { |
| 112 - break; |
| 113 - } |
| 114 - case 1: |
| 115 - { |
| 116 - reloc_addend_value = |
| 117 - read_from_pointer<8>(reloc_addend_ptr); |
| 118 - break; |
| 119 - } |
| 120 - case 2: |
| 121 - { |
| 122 - reloc_addend_value = |
| 123 - read_from_pointer<16>(reloc_addend_ptr); |
| 124 - break; |
| 125 - } |
| 126 - case 4: |
| 127 - { |
| 128 - reloc_addend_value = |
| 129 - read_from_pointer<32>(reloc_addend_ptr); |
| 130 - break; |
| 131 - } |
| 132 - case 8: |
| 133 - { |
| 134 - reloc_addend_value = |
| 135 - read_from_pointer<64>(reloc_addend_ptr); |
| 136 - break; |
| 137 - } |
| 138 - default: |
| 139 - gold_unreachable(); |
| 140 - } |
| 141 - offset = offset + reloc_addend_value; |
| 142 + |
| 143 + // Update the addend value with the SHT_REL addend if |
| 144 + // available. |
| 145 + get_rel_addend(reloc_addend_ptr, *it_addend_size, |
| 146 + &reloc_addend_value); |
| 147 + |
| 148 + // Ignore the addend when it is a negative value. See the |
| 149 + // comments in Merged_symbol_value::value in object.h. |
| 150 + if (reloc_addend_value < 0xffffff00) |
| 151 + offset = offset + reloc_addend_value; |
| 152 |
| 153 section_size_type secn_len; |
| 154 + |
| 155 const unsigned char* str_contents = |
| 156 (it_v->first)->section_contents(it_v->second, |
| 157 &secn_len, |
| 158 false) + offset; |
| 159 + gold_assert (offset < (long long) secn_len); |
| 160 + |
| 161 if ((secn_flags & elfcpp::SHF_STRINGS) != 0) |
| 162 { |
| 163 // String merge section. |
| 164 @@ -489,10 +506,14 @@ get_section_contents(bool first_iteration, |
| 165 } |
| 166 else |
| 167 { |
| 168 - // Use the entsize to determine the length. |
| 169 - buffer.append(reinterpret_cast<const |
| 170 + // Use the entsize to determine the length to copy. |
| 171 + uint64_t bufsize = entsize; |
| 172 + // If entsize is too big, copy all the remaining bytes. |
| 173 + if ((offset + entsize) > secn_len) |
| 174 + bufsize = secn_len - offset; |
| 175 + buffer.append(reinterpret_cast<const |
| 176 char*>(str_contents), |
| 177 - entsize); |
| 178 + bufsize); |
| 179 } |
| 180 buffer.append("@"); |
| 181 } |
OLD | NEW |