[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