[PATCH] x86-64: Check 32-bit PCREL overflow

H.J. Lu hjl.tools@gmail.com
Thu Apr 22 13:25:22 GMT 2021


Check for overflow when finishing 32-bit PCREL relocation in 64-bit
mode.

	PR gas/27763
	* config/tc-i386.c (md_apply_fix): Check for overflow when
	finishing 32-bit PCREL relocation in 64-bit mode.
	 * testsuite/gas/i386/i386.exp: Run PR gas/27763 tests.
	* testsuite/gas/i386/x86-64-rip-2.d: New file.
	* testsuite/gas/i386/x86-64-rip-2.s: Likewise.
	* testsuite/gas/i386/x86-64-rip-inval-1.l: Likewise.
	* testsuite/gas/i386/x86-64-rip-inval-1.s: Likewise.
	* testsuite/gas/i386/x86-64-rip-inval-2.l: Likewise.
	* testsuite/gas/i386/x86-64-rip-inval-2.s: Likewise.
---
 gas/config/tc-i386.c                        | 10 +++++++++-
 gas/testsuite/gas/i386/i386.exp             |  3 +++
 gas/testsuite/gas/i386/x86-64-rip-2.d       | 21 +++++++++++++++++++++
 gas/testsuite/gas/i386/x86-64-rip-2.s       | 10 ++++++++++
 gas/testsuite/gas/i386/x86-64-rip-inval-1.l | 11 +++++++++++
 gas/testsuite/gas/i386/x86-64-rip-inval-1.s |  4 ++++
 gas/testsuite/gas/i386/x86-64-rip-inval-2.l | 11 +++++++++++
 gas/testsuite/gas/i386/x86-64-rip-inval-2.s |  4 ++++
 8 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/i386/x86-64-rip-2.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-rip-2.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-rip-inval-1.l
 create mode 100644 gas/testsuite/gas/i386/x86-64-rip-inval-1.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-rip-inval-2.l
 create mode 100644 gas/testsuite/gas/i386/x86-64-rip-inval-2.s

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index e49d0f53f0b..0bf0d8ec1f9 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -12556,7 +12556,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
   /* Are we finished with this relocation now?  */
   if (fixP->fx_addsy == NULL)
-    fixP->fx_done = 1;
+    {
+      if (flag_code == CODE_64BIT
+	  && fixP->fx_r_type == BFD_RELOC_32_PCREL
+	  && !fits_in_signed_long (value))
+	as_bad_where (fixP->fx_file, fixP->fx_line,
+		      _("0x%llx out range of signed 32bit displacement"),
+		      (long long) value);
+      fixP->fx_done = 1;
+    }
 #if defined (OBJ_COFF) && defined (TE_PE)
   else if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
     {
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index e1dab453b42..a8604caa3ad 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -760,6 +760,9 @@ if [gas_64_check] then {
     }
     run_dump_test "x86-64-rip"
     run_dump_test "x86-64-rip-intel"
+    run_dump_test "x86-64-rip-2"
+    run_list_test "x86-64-rip-inval-1" "-al"
+    run_list_test "x86-64-rip-inval-2" "-al"
     run_dump_test "x86-64-stack"
     run_dump_test "x86-64-stack-intel"
     run_dump_test "x86-64-stack-suffix"
diff --git a/gas/testsuite/gas/i386/x86-64-rip-2.d b/gas/testsuite/gas/i386/x86-64-rip-2.d
new file mode 100644
index 00000000000..bf9ca3997b0
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-rip-2.d
@@ -0,0 +1,21 @@
+#as: -J
+#objdump: -drw --syms
+#name: x86-64 rip addressing 2
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0000000000000000 l       .text	0000000000000000 _start
+0000000080000006 l       .text	0000000000000000 test1
+ffffffff8000000e l       .text	0000000000000000 test2
+00000000f000000e l       .text	0000000000000000 test3
+ffffffff1000000e l       .text	0000000000000000 test4
+
+
+
+Disassembly of section .text:
+
+0000000000000000 <_start>:
+ +0:	48 8b 05 ff ff ff 7f 	mov    0x7fffffff\(%rip\),%rax        # 80000006 <test1>
+ +7:	48 8b 05 00 00 00 80 	mov    -0x80000000\(%rip\),%rax        # ffffffff8000000e <test2>
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-rip-2.s b/gas/testsuite/gas/i386/x86-64-rip-2.s
new file mode 100644
index 00000000000..5ce80e8bb7a
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-rip-2.s
@@ -0,0 +1,10 @@
+	.text
+_start:
+	movq test1(%rip), %rax
+	.set test1, . + 0x7fffffff
+
+	movq test2(%rip), %rax
+	.set test2, . - 0x80000000
+
+	.set test3, . + 0xf0000000
+	.set test4, . - 0xf0000000
diff --git a/gas/testsuite/gas/i386/x86-64-rip-inval-1.l b/gas/testsuite/gas/i386/x86-64-rip-inval-1.l
new file mode 100644
index 00000000000..30756db5661
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-rip-inval-1.l
@@ -0,0 +1,11 @@
+.*: Assembler messages:
+.*:3: Error: 0xffffffff7fffffff out range of signed 32bit displacement
+GAS LISTING .*
+
+
+[ 	]*1[ 	]+\.text
+[ 	]*2[ 	]+_start:
+[ 	]*3[ 	]+\?\?\?\? 488B05FF 		movq test1\(%rip\), %rax
+[ 	]*3[ 	]+FFFF7F
+[ 	]*4[ 	]+\.set test1, \. - 0x80000001
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-rip-inval-1.s b/gas/testsuite/gas/i386/x86-64-rip-inval-1.s
new file mode 100644
index 00000000000..a0e783e59ed
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-rip-inval-1.s
@@ -0,0 +1,4 @@
+	.text
+_start:
+	movq test1(%rip), %rax
+	.set test1, . - 0x80000001
diff --git a/gas/testsuite/gas/i386/x86-64-rip-inval-2.l b/gas/testsuite/gas/i386/x86-64-rip-inval-2.l
new file mode 100644
index 00000000000..c30ada9dc92
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-rip-inval-2.l
@@ -0,0 +1,11 @@
+.*: Assembler messages:
+.*:3: Error: 0x80000000 out range of signed 32bit displacement
+GAS LISTING .*
+
+
+[ 	]*1[ 	]+\.text
+[ 	]*2[ 	]+_start:
+[ 	]*3[ 	]+\?\?\?\? 488B0500 		movq test1\(%rip\), %rax
+[ 	]*3[ 	]+000080
+[ 	]*4[ 	]+\.set test1, \. \+ 0x80000000
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-rip-inval-2.s b/gas/testsuite/gas/i386/x86-64-rip-inval-2.s
new file mode 100644
index 00000000000..9bdc703cf22
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-rip-inval-2.s
@@ -0,0 +1,4 @@
+	.text
+_start:
+	movq test1(%rip), %rax
+	.set test1, . + 0x80000000
-- 
2.30.2



More information about the Binutils mailing list