PATCH: Check 64-bit relocation addend overflow for x32

H.J. Lu hongjiu.lu@intel.com
Sat May 12 12:37:00 GMT 2012


On Wed, May 09, 2012 at 08:27:41PM -0700, H.J. Lu wrote:
> Hi,
> 
> 64-bit relocation addend may overflow for x32.  I checked in it this
> patch to prevent it.

> 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:

It turns out that gcc loop optimization generates code like

	movabsq	$xtrn - 4294967295, %rbp

and expects address wrap around. I checked in this patch to remove
x32 addend overflow for BFD_RELOC_64.


H.J.
---
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 5eb6d0a..82bfc0e 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2012-05-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* config/tc-i386.c (tc_gen_reloc): Remove x32 addend overflow
+	for BFD_RELOC_64.
+
 2012-05-11  Daniel Richard G.  <skunk@iskunk.org>
 
 	PR binutils/14028
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index e33fb6c..ccf54bc 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -9173,25 +9173,6 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
       if (disallow_64bit_reloc)
 	switch (code)
 	  {
-	  case BFD_RELOC_64:
-	    /* Check addend overflow.  */
-	    if (!fits_in_signed_long (fixp->fx_offset))
-	      {
-		bfd_signed_vma addend = fixp->fx_offset;
-		if (addend < 0)
-		  as_bad_where (fixp->fx_file, fixp->fx_line,
-				_("cannot represent relocation %s with "
-				  "addend -0x%" BFD_VMA_FMT "x in x32 "
-				  "mode"),
-				bfd_get_reloc_code_name (code), -addend);
-		else
-		  as_bad_where (fixp->fx_file, fixp->fx_line,
-				_("cannot represent relocation %s with "
-				  "addend 0x%" BFD_VMA_FMT "x in x32 "
-				  "mode"),
-				bfd_get_reloc_code_name (code), addend);
-	      }
-	    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 7559561..f1df950 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2012-05-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* gas/i386/ilp32/ilp32.exp: Don't run reloc64-inval.
+
+	* gas/i386/ilp32/reloc64.s: Add test for -4294967295 addend.
+	* gas/i386/ilp32/reloc64.d: Updated.
+
+	* gas/i386/ilp32/reloc64-inval.l: Removed.
+	* gas/i386/ilp32/reloc64-inval.s: Likewise.
+
 2012-05-09  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* gas/i386/ilp32/ilp32.exp: Run reloc64-inval.
diff --git a/gas/testsuite/gas/i386/ilp32/ilp32.exp b/gas/testsuite/gas/i386/ilp32/ilp32.exp
index 95f3a2d..de43bf2 100644
--- a/gas/testsuite/gas/i386/ilp32/ilp32.exp
+++ b/gas/testsuite/gas/i386/ilp32/ilp32.exp
@@ -26,7 +26,6 @@ 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
deleted file mode 100644
index 1328237..0000000
--- a/gas/testsuite/gas/i386/ilp32/reloc64-inval.l
+++ /dev/null
@@ -1,3 +0,0 @@
-.*: 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
deleted file mode 100644
index 14134aa..0000000
--- a/gas/testsuite/gas/i386/ilp32/reloc64-inval.s
+++ /dev/null
@@ -1,3 +0,0 @@
-	.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 140f24d..c2fd292 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.d
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.d
@@ -60,6 +60,7 @@ Disassembly of section \.text:
 .*[ 	]+R_X86_64_TPOFF32[ 	]+xtrn
 .*[ 	]+R_X86_64_TPOFF32[ 	]+xtrn
 .*[ 	]+R_X86_64_TPOFF32[ 	]+xtrn
+.*[ 	]+R_X86_64_64[ 	]+xtrn\+0x1
 Disassembly of section \.data:
 #...
 .*[ 	]+R_X86_64_32[ 	]+xtrn
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i386/ilp32/reloc64.s
index 3a2dbb8..4149ec2 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.s
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.s
@@ -178,6 +178,7 @@ bad	.byte	xtrn@tpoff
 
 	.text
 	mov	xtrn@tpoff (%rbx), %eax
+	movabsq	$xtrn - 4294967295, %rbp
 
 	.data
 	.quad	xtrn



More information about the Binutils mailing list