x86: Properly handle PLT expression in directive
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 19 Dec 2018 20:21:56 +0000 (12:21 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 19 Dec 2018 20:22:12 +0000 (12:22 -0800)
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.

14 files changed:
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/gas/i386/ilp32/reloc64.l
gas/testsuite/gas/i386/ilp32/reloc64.s
gas/testsuite/gas/i386/reloc32.l
gas/testsuite/gas/i386/reloc32.s
gas/testsuite/gas/i386/reloc64.l
gas/testsuite/gas/i386/reloc64.s
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-x86-64/pr23997a.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr23997b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr23997c.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 00159202d1d2e2b803cc01ea70dea441b935888f..b21680a1589ef0203a2c82f07cf3a506645cce5e 100644 (file)
@@ -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
index 8e25e6c7a04eec60a11aa1224852236d5d618285..764063119d10cbf919e221a9690ff3eb07004b4e 100644 (file)
@@ -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:
index ff4919459717ccaafc6ea1e61bd25c17a2a8d476..7a1808e4e96c1901dcc5d673434e595a6f20e21d 100644 (file)
@@ -51,3 +51,4 @@
 .*:175: Error: .*
 .*:176: Error: .*
 .*:177: Error: .*
+.*:189: Error: .*
index 77764b3c625ceda16f2a7c3e65f01ac632065354..3ab25eff6c001ab88d0284393063f4b2205bc214 100644 (file)
@@ -186,3 +186,4 @@ bad .byte   xtrn@tpoff
        .quad   xtrn - 0x80000000
        .long   xtrn@got - 4
        .long   xtrn@got + 4
+bad    .long   xtrn@plt - .
index 9299445851f780beed480fd5e6e54698394dd41c..3fb3255fc89e9b5e3869ef87ca75a704c997eaec 100644 (file)
@@ -65,4 +65,5 @@
 .*:159: Error: .*
 .*:160: Error: .*
 .*:161: Error: .*
+.*:164: Error: .*
 #pass
index 855dcf578d9039bb49052f75f8d3f688d617ac26..e766a3dcc258f9a4bcc74cecf213399a8f63cf41 100644 (file)
@@ -161,3 +161,4 @@ bad .byte   xtrn@ntpoff
 bad    .byte   xtrn@tpoff
        .long   xtrn@got + 4
        .long   xtrn@got - 4
+bad    .long   xtrn@plt - .
index 5e970cb7b6d84da7ec17bb1c19b6254dd908fda0..6d7a3c70c4da2f7d5cb2f0cfd652f48fd85b7637 100644 (file)
@@ -81,3 +81,4 @@
 .*:218: Error: .*
 .*:219: Error: .*
 .*:220: Error: .*
+.*:227: Error: .*
index 0f9c51e4c8d9f4633f45c130688f8fdc61b60504..bc6f0fa6cc31198b5a7618e49c208b985208011c 100644 (file)
@@ -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 - .
index 17a2e453ab01961cc7c0aba18f7dfcc92b827e57..c7d4a0c543d269506389ea7415d436d81c8cfb60 100644 (file)
@@ -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
index f86a54d27ae6ffa2d42ffbb56f02964516ebe627..b3c489a85de8d9bb87443491c16656d77b03c5ca 100644 (file)
@@ -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 (file)
index 0000000..8d72c62
--- /dev/null
@@ -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 (file)
index 0000000..02cb8f8
--- /dev/null
@@ -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 (file)
index 0000000..3573157
--- /dev/null
@@ -0,0 +1,7 @@
+extern int foo_p;
+
+void *
+get_foo (void)
+{
+  return (void *) ((long) &foo_p + foo_p);
+}
index 75e2546c0c82e6aae7a75c9c0dbdbf55acb409aa..c9e8ecbb1983a6998c8e090f80ce77f8f1b8f5bb 100644 (file)
@@ -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.