PATCH: Check 64-bit relocation addend overflow for x32

H.J. Lu hongjiu.lu@intel.com
Thu May 10 03:27:00 GMT 2012


Hi,

64-bit relocation addend may overflow for x32.  I checked in it this
patch to prevent it.


H.J.
---
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4c49cf9..ee2c264 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2012-05-09  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* elf64-x86-64.c (elf_x86_64_relocate_section): Check addend
+	overflow for R_X86_64_RELATIVE64.
+
 2012-05-08  Ben Cheng  <bccheng@google.com>
 
 	* bfd/elf.c: Preserve the original p_align and p_flags if they are
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index de7fd6f..8eafbf0 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -3681,6 +3681,27 @@ elf_x86_64_relocate_section (bfd *output_bfd,
 		      outrel.r_info = htab->r_info (0,
 						    R_X86_64_RELATIVE64);
 		      outrel.r_addend = relocation + rel->r_addend;
+		      /* Check addend overflow.  */
+		      if ((outrel.r_addend & 0x80000000)
+			  != (rel->r_addend & 0x80000000))
+			{
+			  const char *name;
+			  if (h && h->root.root.string)
+			    name = h->root.root.string;
+			  else
+			    name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+						     sym, NULL);
+			  (*_bfd_error_handler)
+			    (_("%B: addend %ld in relocation %s against "
+			       "symbol `%s' at 0x%lx in section `%A' is "
+			       "out of range"),
+			     input_bfd, input_section,
+			     (long) rel->r_addend,
+			     x86_64_elf_howto_table[r_type].name,
+			     name, (unsigned long) rel->r_offset);
+			  bfd_set_error (bfd_error_bad_value);
+			  return FALSE;
+			}
 		    }
 		  else
 		    {
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2cc6360..3b43ecd 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2012-05-09  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* config/tc-i386.c (tc_gen_reloc): Check x32 addend overflow
+	for BFD_RELOC_64.
+
 2012-05-08  Alan Modra  <amodra@gmail.com>
 
 	* Makefile.am (check_DEJAGNU): Export LC_ALL=C in place of other
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ccf54bc..06f9764 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -9173,6 +9173,17 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
       if (disallow_64bit_reloc)
 	switch (code)
 	  {
+	  case BFD_RELOC_64:
+	    /* Check addend overflow.  */
+	    if ((long long) fixp->fx_offset > 0x7fffffffLL
+		|| (long long) fixp->fx_offset < -0x80000000LL)
+	      {
+		as_bad_where (fixp->fx_file, fixp->fx_line,
+			      _("cannot represent relocation %s with addend %lld in x32 mode"),
+			      bfd_get_reloc_code_name (code),
+			      (long long) fixp->fx_offset);
+	      }
+	    break;
 	  case BFD_RELOC_X86_64_DTPOFF64:
 	  case BFD_RELOC_X86_64_TPOFF64:
 	  case BFD_RELOC_64_PCREL:
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index e9c7bc7..7559561 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2012-05-09  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* gas/i386/ilp32/ilp32.exp: Run reloc64-inval.
+
+	* gas/i386/ilp32/reloc64.s: Add tests for ".quad".
+	* gas/i386/ilp32/reloc64.d: Updated.
+
+	* gas/i386/ilp32/reloc64-inval.l: New file.
+	* gas/i386/ilp32/reloc64-inval.s: Likewise.
+
 2012-05-08  Alan Modra  <amodra@gmail.com>
 
 	* lib/gas-defs.exp (run_dump_test): Don't set LC_ALL here.
diff --git a/gas/testsuite/gas/i386/ilp32/ilp32.exp b/gas/testsuite/gas/i386/ilp32/ilp32.exp
index de43bf2..95f3a2d 100644
--- a/gas/testsuite/gas/i386/ilp32/ilp32.exp
+++ b/gas/testsuite/gas/i386/ilp32/ilp32.exp
@@ -26,6 +26,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check] &&
     }
 
     run_list_test "reloc64" "--defsym _bad_=1"
+    run_list_test "reloc64-inval"
 
     set ASFLAGS "$old_ASFLAGS"
 }
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64-inval.l b/gas/testsuite/gas/i386/ilp32/reloc64-inval.l
new file mode 100644
index 0000000..1328237
--- /dev/null
+++ b/gas/testsuite/gas/i386/ilp32/reloc64-inval.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:2: Error: .*
+.*:3: Error: .*
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64-inval.s b/gas/testsuite/gas/i386/ilp32/reloc64-inval.s
new file mode 100644
index 0000000..14134aa
--- /dev/null
+++ b/gas/testsuite/gas/i386/ilp32/reloc64-inval.s
@@ -0,0 +1,3 @@
+	.data
+	.quad	xtrn + 0x80000000
+	.quad	xtrn - 0x80000001
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.d b/gas/testsuite/gas/i386/ilp32/reloc64.d
index 08c15e4..140f24d 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.d
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.d
@@ -90,3 +90,6 @@ Disassembly of section \.data:
 .*[ 	]+R_X86_64_PC16[ 	]+xtrn
 .*[ 	]+R_X86_64_8[ 	]+xtrn
 .*[ 	]+R_X86_64_PC8[ 	]+xtrn
+.*[ 	]+R_X86_64_64[ 	]+xtrn
+.*[ 	]+R_X86_64_64[ 	]+xtrn\+0x7fffffff
+.*[ 	]+R_X86_64_64[ 	]+xtrn\+0x80000000
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i386/ilp32/reloc64.s
index 3f18d04..3a2dbb8 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.s
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.s
@@ -178,3 +178,8 @@ bad	.byte	xtrn@tpoff
 
 	.text
 	mov	xtrn@tpoff (%rbx), %eax
+
+	.data
+	.quad	xtrn
+	.quad	xtrn + 0x7fffffff
+	.quad	xtrn - 0x80000000
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index ae46fd0..34e8d62 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-09  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* ld-x86-64/ilp32-11.d: New file.
+	* ld-x86-64/ilp32-11.s: Likewise.
+
+	* ld-x86-64/x86-64.exp: Run ilp32-11.
+
 2012-05-05  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/14052
diff --git a/ld/testsuite/ld-x86-64/ilp32-11.d b/ld/testsuite/ld-x86-64/ilp32-11.d
new file mode 100644
index 0000000..7240c58
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-11.d
@@ -0,0 +1,3 @@
+#as: --x32
+#ld: -shared -melf32_x86_64
+#error: .*addend 2147483647 in relocation R_X86_64_64 against symbol `.text' at 0x0 in section `.data.rel.local' is out of range
diff --git a/ld/testsuite/ld-x86-64/ilp32-11.s b/ld/testsuite/ld-x86-64/ilp32-11.s
new file mode 100644
index 0000000..2c85385
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-11.s
@@ -0,0 +1,9 @@
+	.section	.data.rel.local,"aw",@progbits
+	.align 8
+.Ljmp:
+	.quad	func + 0x7fffffff
+
+	.text
+	.type	func, @function
+func:
+	ret
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 27174d5..e8afbc2 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -253,6 +253,7 @@ run_dump_test "ilp32-7"
 run_dump_test "ilp32-8"
 run_dump_test "ilp32-9"
 run_dump_test "ilp32-10"
+run_dump_test "ilp32-11"
 run_dump_test "ia32-1"
 run_dump_test "ia32-2"
 run_dump_test "ia32-3"



More information about the Binutils mailing list