This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_26-branch] 2016-02-05 Sriraman Tallam <tmsriram at google dot com>


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d114b830426300f80302ca03ff4322942f63c615

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:
---
 gold/ChangeLog |   8 ++++
 gold/icf.cc    | 115 ++++++++++++++++++++++++++++++++++-----------------------
 2 files changed, 76 insertions(+), 47 deletions(-)

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-16  Roland McGrath  <mcgrathr@google.com>
 
 	PR ld/17473
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("@");
                 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]