summaryrefslogtreecommitdiffstats
path: root/binutils-2.25
diff options
context:
space:
mode:
authorYunlian Jiang <yunlian@google.com>2016-04-01 09:50:02 -0700
committerYunlian Jiang <yunlian@google.com>2016-04-01 17:03:50 +0000
commit78eb6804689b812b374e2e5d248a96977f13ffd1 (patch)
treeeda2dd8b3e39e2654666a6e7cb3c93c892c9fdd5 /binutils-2.25
parent066607388945f542727bd5035fb8d84bfd798034 (diff)
downloadtoolchain_binutils-78eb6804689b812b374e2e5d248a96977f13ffd1.tar.gz
toolchain_binutils-78eb6804689b812b374e2e5d248a96977f13ffd1.tar.bz2
toolchain_binutils-78eb6804689b812b374e2e5d248a96977f13ffd1.zip
Backport upstream CL to fix x86_32 clang segfaults.
Upstream patch being backported: commit 84d543b7ed93bf6511cdf45791f4f0b717dfb718 Author: Sriraman Tallam <tmsriram@google.com> Date: Fri Feb 5 15:07:45 2016 -0800 2016-02-05 Sriraman Tallam <tmsriram@google.com> * 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. Tested via cbuildbot for ChromeOS and build on Android mnc-dr-release for hammerhead
Diffstat (limited to 'binutils-2.25')
-rw-r--r--binutils-2.25/gold/ChangeLog10
-rw-r--r--binutils-2.25/gold/icf.cc115
2 files changed, 78 insertions, 47 deletions
diff --git a/binutils-2.25/gold/ChangeLog b/binutils-2.25/gold/ChangeLog
index fc4250e7..c222155a 100644
--- a/binutils-2.25/gold/ChangeLog
+++ b/binutils-2.25/gold/ChangeLog
@@ -1,3 +1,13 @@
+2016-02-05 Sriraman Tallam <tmsriram@google.com>
+
+ * 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.
+
+
2016-02-26 Egor Kochetov <egor.kochetov@intel.com>
Cary Coutant <ccoutant@gmail.com>
diff --git a/binutils-2.25/gold/icf.cc b/binutils-2.25/gold/icf.cc
index ad887154..1ae18291 100644
--- a/binutils-2.25/gold/icf.cc
+++ b/binutils-2.25/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("@");
}