x86: Properly handle PLT expression in directive

Message ID 20181219202304.11882-1-hjl.tools@gmail.com
State New
Headers show
Series
  • x86: Properly handle PLT expression in directive
Related show

Commit Message

H.J. Lu Dec. 19, 2018, 8:23 p.m.
For PLT expressions, we should subtract the PLT relocation size only for
jump instructions.  Since PLT relocations are PC relative, we only allow
"symbol@PLT" in PLT expression.

gas/

	PR gas/23997
	* config/tc-i386.c (x86_cons): Check for invalid PLT expression.
	(md_apply_fix): Subtract the PLT relocation size only for jump
	instructions.
	* testsuite/gas/i386/reloc32.s: Add test for invalid PLT
	expression.
	* testsuite/gas/i386/reloc64.s: Likewise.
	* testsuite/gas/i386/ilp32/reloc64.s: Likewise.
	* testsuite/gas/i386/reloc32.l: Updated.
	* testsuite/gas/i386/reloc64.l: Likewise.
	* testsuite/gas/i386/ilp32/reloc64.l: Likewise.

ld/

	PR gas/23997
	* testsuite/ld-i386/i386.exp: Run PR gas/23997 test.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-x86-64/pr23997a.s: New file.
	* testsuite/ld-x86-64/pr23997b.c: Likewise.
	* testsuite/ld-x86-64/pr23997c.c: Likewise.
---
 gas/ChangeLog                          | 14 ++++++++++++++
 gas/config/tc-i386.c                   | 17 ++++++++++++++---
 gas/testsuite/gas/i386/ilp32/reloc64.l |  1 +
 gas/testsuite/gas/i386/ilp32/reloc64.s |  1 +
 gas/testsuite/gas/i386/reloc32.l       |  1 +
 gas/testsuite/gas/i386/reloc32.s       |  1 +
 gas/testsuite/gas/i386/reloc64.l       |  1 +
 gas/testsuite/gas/i386/reloc64.s       |  1 +
 ld/ChangeLog                           |  9 +++++++++
 ld/testsuite/ld-i386/i386.exp          |  9 +++++++++
 ld/testsuite/ld-x86-64/pr23997a.s      |  6 ++++++
 ld/testsuite/ld-x86-64/pr23997b.c      | 25 +++++++++++++++++++++++++
 ld/testsuite/ld-x86-64/pr23997c.c      |  7 +++++++
 ld/testsuite/ld-x86-64/x86-64.exp      |  8 ++++++++
 14 files changed, 98 insertions(+), 3 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pr23997a.s
 create mode 100644 ld/testsuite/ld-x86-64/pr23997b.c
 create mode 100644 ld/testsuite/ld-x86-64/pr23997c.c

-- 
2.19.2

Patch

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 00159202d1..b21680a158 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,17 @@ 
+2018-12-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR gas/23997
+	* config/tc-i386.c (x86_cons): Check for invalid PLT expression.
+	(md_apply_fix): Subtract the PLT relocation size only for jump
+	instructions.
+	* testsuite/gas/i386/reloc32.s: Add test for invalid PLT
+	expression.
+	* testsuite/gas/i386/reloc64.s: Likewise.
+	* testsuite/gas/i386/ilp32/reloc64.s: Likewise.
+	* testsuite/gas/i386/reloc32.l: Updated.
+	* testsuite/gas/i386/reloc64.l: Likewise.
+	* testsuite/gas/i386/ilp32/reloc64.l: Likewise.
+
 2018-12-14  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/23900
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 8e25e6c7a0..764063119d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -8919,6 +8919,15 @@  x86_cons (expressionS *exp, int size)
 	      as_bad (_("missing or invalid expression `%s'"), save);
 	      *input_line_pointer = c;
 	    }
+	  else if ((got_reloc == BFD_RELOC_386_PLT32
+		    || got_reloc == BFD_RELOC_X86_64_PLT32)
+		   && exp->X_op != O_symbol)
+	    {
+	      char c = *input_line_pointer;
+	      *input_line_pointer = 0;
+	      as_bad (_("invalid PLT expression `%s'"), save);
+	      *input_line_pointer = c;
+	    }
 	}
     }
   else
@@ -10533,9 +10542,11 @@  md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       {
       case BFD_RELOC_386_PLT32:
       case BFD_RELOC_X86_64_PLT32:
-	/* Make the jump instruction point to the address of the operand.  At
-	   runtime we merely add the offset to the actual PLT entry.  */
-	value = -4;
+	/* Make the jump instruction point to the address of the operand.
+	   At runtime we merely add the offset to the actual PLT entry.
+	   NB: Subtract the offset size only for jump instructions.  */
+	if (fixP->fx_pcrel)
+	  value = -4;
 	break;
 
       case BFD_RELOC_386_TLS_GD:
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.l b/gas/testsuite/gas/i386/ilp32/reloc64.l
index ff49194597..7a1808e4e9 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.l
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.l
@@ -51,3 +51,4 @@ 
 .*:175: Error: .*
 .*:176: Error: .*
 .*:177: Error: .*
+.*:189: Error: .*
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i386/ilp32/reloc64.s
index 77764b3c62..3ab25eff6c 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.s
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.s
@@ -186,3 +186,4 @@  bad	.byte	xtrn@tpoff
 	.quad	xtrn - 0x80000000
 	.long	xtrn@got - 4
 	.long	xtrn@got + 4
+bad	.long	xtrn@plt - .
diff --git a/gas/testsuite/gas/i386/reloc32.l b/gas/testsuite/gas/i386/reloc32.l
index 9299445851..3fb3255fc8 100644
--- a/gas/testsuite/gas/i386/reloc32.l
+++ b/gas/testsuite/gas/i386/reloc32.l
@@ -65,4 +65,5 @@ 
 .*:159: Error: .*
 .*:160: Error: .*
 .*:161: Error: .*
+.*:164: Error: .*
 #pass
diff --git a/gas/testsuite/gas/i386/reloc32.s b/gas/testsuite/gas/i386/reloc32.s
index 855dcf578d..e766a3dcc2 100644
--- a/gas/testsuite/gas/i386/reloc32.s
+++ b/gas/testsuite/gas/i386/reloc32.s
@@ -161,3 +161,4 @@  bad	.byte	xtrn@ntpoff
 bad	.byte	xtrn@tpoff
 	.long	xtrn@got + 4
 	.long	xtrn@got - 4
+bad	.long	xtrn@plt - .
diff --git a/gas/testsuite/gas/i386/reloc64.l b/gas/testsuite/gas/i386/reloc64.l
index 5e970cb7b6..6d7a3c70c4 100644
--- a/gas/testsuite/gas/i386/reloc64.l
+++ b/gas/testsuite/gas/i386/reloc64.l
@@ -81,3 +81,4 @@ 
 .*:218: Error: .*
 .*:219: Error: .*
 .*:220: Error: .*
+.*:227: Error: .*
diff --git a/gas/testsuite/gas/i386/reloc64.s b/gas/testsuite/gas/i386/reloc64.s
index 0f9c51e4c8..bc6f0fa6cc 100644
--- a/gas/testsuite/gas/i386/reloc64.s
+++ b/gas/testsuite/gas/i386/reloc64.s
@@ -224,3 +224,4 @@  bad	.byte	xtrn@gotplt
 	mov	xtrn(,%ebx), %eax
 	vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
 	addr32 vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
+bad	.long	xtrn@plt - .
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 17a2e453ab..c7d4a0c543 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@ 
+2018-12-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR gas/23997
+	* testsuite/ld-i386/i386.exp: Run PR gas/23997 test.
+	* testsuite/ld-x86-64/x86-64.exp: Likewise.
+	* testsuite/ld-x86-64/pr23997a.s: New file.
+	* testsuite/ld-x86-64/pr23997b.c: Likewise.
+	* testsuite/ld-x86-64/pr23997c.c: Likewise.
+
 2018-12-19  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* testsuite/ld-x86-64/x86-64.exp: Rename PR ld/22842 run-time
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index f86a54d27a..b3c489a85d 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -1420,6 +1420,15 @@  if { [isnative]
 	    "pr22842" \
 	    "pass.out" \
 	] \
+	[list \
+	    "Run pr23997" \
+	    "" \
+	    "" \
+	    { ../ld-x86-64/pr23997a.s ../ld-x86-64/pr23997b.c \
+	      ../ld-x86-64/pr23997c.c } \
+	    "pr23997" \
+	    "pass.out" \
+	] \
     ]
 
     if { [at_least_gcc_version 5 0] } {
diff --git a/ld/testsuite/ld-x86-64/pr23997a.s b/ld/testsuite/ld-x86-64/pr23997a.s
new file mode 100644
index 0000000000..8d72c626a3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr23997a.s
@@ -0,0 +1,6 @@ 
+	.text
+	.p2align 3
+	.globl foo_p
+foo_p:
+	.long foo@plt
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/pr23997b.c b/ld/testsuite/ld-x86-64/pr23997b.c
new file mode 100644
index 0000000000..02cb8f8f7f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr23997b.c
@@ -0,0 +1,25 @@ 
+#include <stdio.h>
+
+typedef void (*func_t) (void);
+
+extern func_t get_foo (void);
+
+void
+foo (void)
+{
+}
+
+int
+main ()
+{
+  func_t p;
+
+  foo ();
+  p = get_foo ();
+  p ();
+
+  if (foo == p)
+    printf ("PASS\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-x86-64/pr23997c.c b/ld/testsuite/ld-x86-64/pr23997c.c
new file mode 100644
index 0000000000..357315751d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr23997c.c
@@ -0,0 +1,7 @@ 
+extern int foo_p;
+
+void *
+get_foo (void)
+{
+  return (void *) ((long) &foo_p + foo_p);
+}
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 75e2546c0c..c9e8ecbb19 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1594,6 +1594,14 @@  if { [isnative] && [which $CC] != 0 } {
 	    "pr22842" \
 	    "pass.out" \
 	] \
+	[list \
+	    "Run pr23997" \
+	    "" \
+	    "" \
+	    { pr23997a.s pr23997b.c pr23997c.c } \
+	    "pr23997" \
+	    "pass.out" \
+	] \
     ]
 
     # Run-time tests which require working ifunc attribute support.