| Index: third_party/binutils/icf-rel.patch
|
| diff --git a/third_party/binutils/icf-rel.patch b/third_party/binutils/icf-rel.patch
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1747fccfaedb82663c83178111c7ed8a7d50599d
|
| --- /dev/null
|
| +++ b/third_party/binutils/icf-rel.patch
|
| @@ -0,0 +1,181 @@
|
| +commit d114b830426300f80302ca03ff4322942f63c615
|
| +Author: Roland McGrath <mcgrathr@chromium.org>
|
| +Date: Thu May 5 13:12:40 2016 -0700
|
| +
|
| + 2016-02-05 Sriraman Tallam <tmsriram@google.com>
|
| +
|
| + PR gold/19047
|
| + * icf.cc (get_rel_addend): New function.
|
| + (get_section_contents): Move merge section addend computation to a
|
| + new function. Ignore negative values for SHT_REL and SHT_RELA addends.
|
| + Fix bug to not read past the length of the section.
|
| +
|
| + Fix bug related to addend computation for MERGE sections.
|
| +
|
| + (cherry picked from commit 84d543b7ed93bf6511cdf45791f4f0b717dfb718)
|
| +
|
| +diff --git a/gold/ChangeLog b/gold/ChangeLog
|
| +index 92b26ba..ec8dacb 100644
|
| +--- a/gold/ChangeLog
|
| ++++ b/gold/ChangeLog
|
| +@@ -1,3 +1,11 @@
|
| ++2016-02-05 Sriraman Tallam <tmsriram@google.com>
|
| ++
|
| ++ PR gold/19047
|
| ++ * icf.cc (get_rel_addend): New function.
|
| ++ (get_section_contents): Move merge section addend computation to a
|
| ++ new function. Ignore negative values for SHT_REL and SHT_RELA addends.
|
| ++ Fix bug to not read past the length of the section.
|
| ++
|
| + 2015-12-17 Peter Collingbourne <pcc@google.com>
|
| +
|
| + PR gold/18780
|
| +diff --git a/gold/icf.cc b/gold/icf.cc
|
| +index 96b7f2d..663d579 100644
|
| +--- a/gold/icf.cc
|
| ++++ b/gold/icf.cc
|
| +@@ -213,6 +213,45 @@ preprocess_for_unique_sections(const std::vector<Section_id>& id_section,
|
| + }
|
| + }
|
| +
|
| ++// For SHF_MERGE sections that use REL relocations, the addend is stored in
|
| ++// the text section at the relocation offset. Read the addend value given
|
| ++// the pointer to the addend in the text section and the addend size.
|
| ++// Update the addend value if a valid addend is found.
|
| ++// Parameters:
|
| ++// RELOC_ADDEND_PTR : Pointer to the addend in the text section.
|
| ++// ADDEND_SIZE : The size of the addend.
|
| ++// RELOC_ADDEND_VALUE : Pointer to the addend that is updated.
|
| ++
|
| ++inline void
|
| ++get_rel_addend(const unsigned char* reloc_addend_ptr,
|
| ++ const unsigned int addend_size,
|
| ++ uint64_t* reloc_addend_value)
|
| ++{
|
| ++ switch (addend_size)
|
| ++ {
|
| ++ case 0:
|
| ++ break;
|
| ++ case 1:
|
| ++ *reloc_addend_value =
|
| ++ read_from_pointer<8>(reloc_addend_ptr);
|
| ++ break;
|
| ++ case 2:
|
| ++ *reloc_addend_value =
|
| ++ read_from_pointer<16>(reloc_addend_ptr);
|
| ++ break;
|
| ++ case 4:
|
| ++ *reloc_addend_value =
|
| ++ read_from_pointer<32>(reloc_addend_ptr);
|
| ++ break;
|
| ++ case 8:
|
| ++ *reloc_addend_value =
|
| ++ read_from_pointer<64>(reloc_addend_ptr);
|
| ++ break;
|
| ++ default:
|
| ++ gold_unreachable();
|
| ++ }
|
| ++}
|
| ++
|
| + // This returns the buffer containing the section's contents, both
|
| + // text and relocs. Relocs are differentiated as those pointing to
|
| + // sections that could be folded and those that cannot. Only relocs
|
| +@@ -397,58 +436,36 @@ get_section_contents(bool first_iteration,
|
| + uint64_t entsize =
|
| + (it_v->first)->section_entsize(it_v->second);
|
| + long long offset = it_a->first;
|
| +-
|
| +- unsigned long long addend = it_a->second;
|
| +- // Ignoring the addend when it is a negative value. See the
|
| +- // comments in Merged_symbol_value::Value in object.h.
|
| +- if (addend < 0xffffff00)
|
| +- offset = offset + addend;
|
| +-
|
| +- // For SHT_REL relocation sections, the addend is stored in the
|
| +- // text section at the relocation offset.
|
| +- uint64_t reloc_addend_value = 0;
|
| ++ // Handle SHT_RELA and SHT_REL addends, only one of these
|
| ++ // addends exists.
|
| ++ // Get the SHT_RELA addend. For RELA relocations, we have
|
| ++ // the addend from the relocation.
|
| ++ uint64_t reloc_addend_value = it_a->second;
|
| ++
|
| ++ // Handle SHT_REL addends.
|
| ++ // For REL relocations, we need to fetch the addend from the
|
| ++ // section contents.
|
| + const unsigned char* reloc_addend_ptr =
|
| + contents + static_cast<unsigned long long>(*it_o);
|
| +- switch(*it_addend_size)
|
| +- {
|
| +- case 0:
|
| +- {
|
| +- break;
|
| +- }
|
| +- case 1:
|
| +- {
|
| +- reloc_addend_value =
|
| +- read_from_pointer<8>(reloc_addend_ptr);
|
| +- break;
|
| +- }
|
| +- case 2:
|
| +- {
|
| +- reloc_addend_value =
|
| +- read_from_pointer<16>(reloc_addend_ptr);
|
| +- break;
|
| +- }
|
| +- case 4:
|
| +- {
|
| +- reloc_addend_value =
|
| +- read_from_pointer<32>(reloc_addend_ptr);
|
| +- break;
|
| +- }
|
| +- case 8:
|
| +- {
|
| +- reloc_addend_value =
|
| +- read_from_pointer<64>(reloc_addend_ptr);
|
| +- break;
|
| +- }
|
| +- default:
|
| +- gold_unreachable();
|
| +- }
|
| +- offset = offset + reloc_addend_value;
|
| ++
|
| ++ // Update the addend value with the SHT_REL addend if
|
| ++ // available.
|
| ++ get_rel_addend(reloc_addend_ptr, *it_addend_size,
|
| ++ &reloc_addend_value);
|
| ++
|
| ++ // Ignore the addend when it is a negative value. See the
|
| ++ // comments in Merged_symbol_value::value in object.h.
|
| ++ if (reloc_addend_value < 0xffffff00)
|
| ++ offset = offset + reloc_addend_value;
|
| +
|
| + section_size_type secn_len;
|
| ++
|
| + const unsigned char* str_contents =
|
| + (it_v->first)->section_contents(it_v->second,
|
| + &secn_len,
|
| + false) + offset;
|
| ++ gold_assert (offset < (long long) secn_len);
|
| ++
|
| + if ((secn_flags & elfcpp::SHF_STRINGS) != 0)
|
| + {
|
| + // String merge section.
|
| +@@ -489,10 +506,14 @@ get_section_contents(bool first_iteration,
|
| + }
|
| + else
|
| + {
|
| +- // Use the entsize to determine the length.
|
| +- buffer.append(reinterpret_cast<const
|
| ++ // Use the entsize to determine the length to copy.
|
| ++ uint64_t bufsize = entsize;
|
| ++ // If entsize is too big, copy all the remaining bytes.
|
| ++ if ((offset + entsize) > secn_len)
|
| ++ bufsize = secn_len - offset;
|
| ++ buffer.append(reinterpret_cast<const
|
| + char*>(str_contents),
|
| +- entsize);
|
| ++ bufsize);
|
| + }
|
| + buffer.append("@");
|
| + }
|
|
|