x86-64: Generate branch with PLT32 relocation
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 13 Feb 2018 15:34:22 +0000 (07:34 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 13 Feb 2018 15:34:36 +0000 (07:34 -0800)
Since there is no need to prepare for PLT branch on x86-64, generate
R_X86_64_PLT32, instead of R_X86_64_PC32, if possible, which can be
used as a marker for 32-bit PC-relative branches.

To compile Linux kernel, this patch:

From: "H.J. Lu" <hjl.tools@gmail.com>
Subject: [PATCH] x86: Treat R_X86_64_PLT32 as R_X86_64_PC32

On i386, there are 2 types of PLTs, PIC and non-PIC.  PIE and shared
objects must use PIC PLT.  To use PIC PLT, you need to load
_GLOBAL_OFFSET_TABLE_ into EBX first.  There is no need for that on
x86-64 since x86-64 uses PC-relative PLT.

On x86-64, for 32-bit PC-relative branches, we can generate PLT32
relocation, instead of PC32 relocation, which can also be used as
a marker for 32-bit PC-relative branches.  Linker can always reduce
PLT32 relocation to PC32 if function is defined locally.   Local
functions should use PC32 relocation.  As far as Linux kernel is
concerned, R_X86_64_PLT32 can be treated the same as R_X86_64_PC32
since Linux kernel doesn't use PLT.

is needed.  It is available on hjl/plt32/master branch at

https://github.com/hjl-tools/linux

bfd/

PR gas/22791
* elf64-x86-64.c (is_32bit_relative_branch): Removed.
(elf_x86_64_relocate_section): Check PIC relocations in PIE.
Remove is_32bit_relative_branch usage.  Disallow PC32 reloc
against protected function in shared object.

gas/

PR gas/22791
* config/tc-i386.c (need_plt32_p): New function.
(output_jump): Generate BFD_RELOC_X86_64_PLT32 if possible.
(md_estimate_size_before_relax): Likewise.
* testsuite/gas/i386/reloc64.d: Updated.
* testsuite/gas/i386/x86-64-jump.d: Likewise.
* testsuite/gas/i386/x86-64-mpx-branch-1.d: Likewise.
* testsuite/gas/i386/x86-64-mpx-branch-2.d: Likewise.
* testsuite/gas/i386/x86-64-relax-2.d: Likewise.
* testsuite/gas/i386/x86-64-relax-3.d: Likewise.
* testsuite/gas/i386/ilp32/reloc64.d: Likewise.
* testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise.

ld/

PR gas/22791
* testsuite/ld-x86-64/mpx1c.rd: Updated.
* testsuite/ld-x86-64/pr22791-1.err: New file.
* testsuite/ld-x86-64/pr22791-1a.c: Likewise.
* testsuite/ld-x86-64/pr22791-1b.s: Likewise.
* testsuite/ld-x86-64/pr22791-2.rd: Likewise.
* testsuite/ld-x86-64/pr22791-2a.s: Likewise.
* testsuite/ld-x86-64/pr22791-2b.c: Likewise.
* testsuite/ld-x86-64/pr22791-2c.s: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/22791 tests.

22 files changed:
bfd/ChangeLog
bfd/elf64-x86-64.c
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/gas/i386/ilp32/reloc64.d
gas/testsuite/gas/i386/ilp32/x86-64-branch.d
gas/testsuite/gas/i386/reloc64.d
gas/testsuite/gas/i386/x86-64-jump.d
gas/testsuite/gas/i386/x86-64-mpx-branch-1.d
gas/testsuite/gas/i386/x86-64-mpx-branch-2.d
gas/testsuite/gas/i386/x86-64-relax-2.d
gas/testsuite/gas/i386/x86-64-relax-3.d
ld/ChangeLog
ld/testsuite/ld-x86-64/mpx1c.rd
ld/testsuite/ld-x86-64/pr22791-1.err [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22791-1a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22791-1b.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22791-2.rd [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22791-2a.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22791-2b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22791-2c.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 1dcfe41..726225a 100644 (file)
@@ -1,3 +1,11 @@
+2018-02-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/22791
+       * elf64-x86-64.c (is_32bit_relative_branch): Removed.
+       (elf_x86_64_relocate_section): Check PIC relocations in PIE.
+       Remove is_32bit_relative_branch usage.  Disallow PC32 reloc
+       against protected function in shared object.
+
 2018-02-13  Sergei Trofimovich  <slyfox@inbox.ru>
 
        PR 22828
index ad66840..0e4bb2e 100644 (file)
@@ -2307,24 +2307,6 @@ elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - static_tls_size - htab->tls_sec->vma;
 }
 
-/* Is the instruction before OFFSET in CONTENTS a 32bit relative
-   branch?  */
-
-static bfd_boolean
-is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
-{
-  /* Opcode            Instruction
-     0xe8              call
-     0xe9              jump
-     0x0f 0x8x         conditional jump */
-  return ((offset > 0
-          && (contents [offset - 1] == 0xe8
-              || contents [offset - 1] == 0xe9))
-         || (offset > 1
-             && contents [offset - 2] == 0x0f
-             && (contents [offset - 1] & 0xf0) == 0x80));
-}
-
 /* Relocate an x86_64 ELF section.  */
 
 static bfd_boolean
@@ -3023,14 +3005,18 @@ do_ifunc_pointer:
        case R_X86_64_PC32:
        case R_X86_64_PC32_BND:
          /* Don't complain about -fPIC if the symbol is undefined when
-            building executable unless it is unresolved weak symbol or
-            -z nocopyreloc is used.  */
+            building executable unless it is unresolved weak symbol,
+            references a dynamic definition in PIE or -z nocopyreloc
+            is used.  */
          if ((input_section->flags & SEC_ALLOC) != 0
              && (input_section->flags & SEC_READONLY) != 0
              && h != NULL
              && ((bfd_link_executable (info)
                   && ((h->root.type == bfd_link_hash_undefweak
                        && !resolved_to_zero)
+                      || (bfd_link_pie (info)
+                          && !h->def_regular
+                          && h->def_dynamic)
                       || ((info->nocopyreloc
                            || (eh->def_protected
                                && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
@@ -3039,26 +3025,21 @@ do_ifunc_pointer:
                  || bfd_link_dll (info)))
            {
              bfd_boolean fail = FALSE;
-             bfd_boolean branch
-               = ((r_type == R_X86_64_PC32
-                   || r_type == R_X86_64_PC32_BND)
-                  && is_32bit_relative_branch (contents, rel->r_offset));
-
              if (SYMBOL_REFERENCES_LOCAL_P (info, h))
                {
                  /* Symbol is referenced locally.  Make sure it is
-                    defined locally or for a branch.  */
-                 fail = (!(h->def_regular || ELF_COMMON_DEF_P (h))
-                         && !branch);
+                    defined locally.  */
+                 fail = !(h->def_regular || ELF_COMMON_DEF_P (h));
                }
              else if (!(bfd_link_pie (info)
                         && (h->needs_copy || eh->needs_copy)))
                {
                  /* Symbol doesn't need copy reloc and isn't referenced
-                    locally.  We only allow branch to symbol with
-                    non-default visibility. */
-                 fail = (!branch
-                         || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
+                    locally.  Address of protected function may not be
+                    reachable at run-time.  */
+                 fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                         || (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED
+                             && h->type == STT_FUNC));
                }
 
              if (fail)
index 97b3581..e66e8ce 100644 (file)
@@ -1,3 +1,18 @@
+2018-02-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/22791
+       * config/tc-i386.c (need_plt32_p): New function.
+       (output_jump): Generate BFD_RELOC_X86_64_PLT32 if possible.
+       (md_estimate_size_before_relax): Likewise.
+       * testsuite/gas/i386/reloc64.d: Updated.
+       * testsuite/gas/i386/x86-64-jump.d: Likewise.
+       * testsuite/gas/i386/x86-64-mpx-branch-1.d: Likewise.
+       * testsuite/gas/i386/x86-64-mpx-branch-2.d: Likewise.
+       * testsuite/gas/i386/x86-64-relax-2.d: Likewise.
+       * testsuite/gas/i386/x86-64-relax-3.d: Likewise.
+       * testsuite/gas/i386/ilp32/reloc64.d: Likewise.
+       * testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise.
+
 2018-02-13  Maciej W. Rozycki  <macro@mips.com>
 
        * testsuite/gas/mips/loongson-3a-2.d: Rename test.
index 552c1b8..1a5be1b 100644 (file)
@@ -7023,12 +7023,46 @@ output_branch (void)
   frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p);
 }
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+/* Return TRUE iff PLT32 relocation should be used for branching to
+   symbol S.  */
+
+static bfd_boolean
+need_plt32_p (symbolS *s)
+{
+  /* PLT32 relocation is ELF only.  */
+  if (!IS_ELF)
+    return FALSE;
+
+  /* Since there is no need to prepare for PLT branch on x86-64, we
+     can generate R_X86_64_PLT32, instead of R_X86_64_PC32, which can
+     be used as a marker for 32-bit PC-relative branches.  */
+  if (!object_64bit)
+    return FALSE;
+
+  /* Weak or undefined symbol need PLT32 relocation.  */
+  if (S_IS_WEAK (s) || !S_IS_DEFINED (s))
+    return TRUE;
+
+  /* Non-global symbol doesn't need PLT32 relocation.  */
+  if (! S_IS_EXTERNAL (s))
+    return FALSE;
+
+  /* Other global symbols need PLT32 relocation.  NB: Symbol with
+     non-default visibilities are treated as normal global symbol
+     so that PLT32 relocation can be used as a marker for 32-bit
+     PC-relative branches.  It is useful for linker relaxation.  */
+  return TRUE;
+}
+#endif
+
 static void
 output_jump (void)
 {
   char *p;
   int size;
   fixS *fixP;
+  bfd_reloc_code_real_type jump_reloc = i.reloc[0];
 
   if (i.tm.opcode_modifier.jumpbyte)
     {
@@ -7096,8 +7130,17 @@ output_jump (void)
       abort ();
     }
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+  if (size == 4
+      && jump_reloc == NO_RELOC
+      && need_plt32_p (i.op[0].disps->X_add_symbol))
+    jump_reloc = BFD_RELOC_X86_64_PLT32;
+#endif
+
+  jump_reloc = reloc (size, 1, 1, jump_reloc);
+
   fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
-                     i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
+                     i.op[0].disps, 1, jump_reloc);
 
   /* All jumps handled here are signed, but don't use a signed limit
      check for 32 and 16 bit jumps as we want to allow wrap around at
@@ -9315,6 +9358,10 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
        reloc_type = (enum bfd_reloc_code_real) fragP->fr_var;
       else if (size == 2)
        reloc_type = BFD_RELOC_16_PCREL;
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+      else if (need_plt32_p (fragP->fr_symbol))
+       reloc_type = BFD_RELOC_X86_64_PLT32;
+#endif
       else
        reloc_type = BFD_RELOC_32_PCREL;
 
index 53083f3..f6bc628 100644 (file)
@@ -16,7 +16,7 @@ Disassembly of section \.text:
 .*[    ]+R_X86_64_PC8[         ]+xtrn\+0x0*1
 .*[    ]+R_X86_64_PC32[        ]+xtrn-0x0*4
 .*[    ]+R_X86_64_PC32[        ]+xtrn-0x0*4
-.*[    ]+R_X86_64_PC32[        ]+xtrn-0x0*4
+.*[    ]+R_X86_64_PLT32[       ]+xtrn-0x0*4
 .*[    ]+R_X86_64_PC8[         ]+xtrn-0x0*1
 .*[    ]+R_X86_64_GOT32[       ]+xtrn
 .*[    ]+R_X86_64_GOT32[       ]+xtrn
index 915dbf3..45ab617 100644 (file)
@@ -20,9 +20,9 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    66 ff 20                data16 jmpq \*\(%rax\)
 [      ]*[a-f0-9]+:    e8 00 00 00 00          callq  0x1f     1b: R_X86_64_PC32       \*ABS\*\+0x10003c
 [      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   0x24     20: R_X86_64_PC32       \*ABS\*\+0x10003c
-[      ]*[a-f0-9]+:    66 e8 00 00 00 00       data16 callq 0x2a       26: R_X86_64_PC32       foo-0x4
-[      ]*[a-f0-9]+:    66 e9 00 00 00 00       data16 jmpq 0x30        2c: R_X86_64_PC32       foo-0x4
-[      ]*[a-f0-9]+:    66 0f 82 00 00 00 00    data16 jb 0x37  33: R_X86_64_PC32       foo-0x4
+[      ]*[a-f0-9]+:    66 e8 00 00 00 00       data16 callq 0x2a       26: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    66 e9 00 00 00 00       data16 jmpq 0x30        2c: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    66 0f 82 00 00 00 00    data16 jb 0x37  33: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
 [      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
index a7fd3d6..4cf884d 100644 (file)
@@ -18,7 +18,7 @@ Disassembly of section \.text:
 .*[    ]+R_X86_64_PC8[         ]+xtrn\+0x0*1
 .*[    ]+R_X86_64_PC32[        ]+xtrn-0x0*4
 .*[    ]+R_X86_64_PC32[        ]+xtrn-0x0*4
-.*[    ]+R_X86_64_PC32[        ]+xtrn-0x0*4
+.*[    ]+R_X86_64_PLT32[       ]+xtrn-0x0*4
 .*[    ]+R_X86_64_PC8[         ]+xtrn-0x0*1
 .*[    ]+R_X86_64_GOT64[       ]+xtrn
 .*[    ]+R_X86_64_GOT32[       ]+xtrn
index edb34e6..9f7b4b4 100644 (file)
@@ -8,7 +8,7 @@ Disassembly of section .text:
 
 0+ <.text>:
 [      ]*[a-f0-9]+:    eb fe                   jmp    (0x0|0 <.text>)
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   0x7      3: R_X86_64_PC32        xxx-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   0x7      3: R_X86_64_PLT32       xxx-0x4
 [      ]*[a-f0-9]+:    ff 24 25 00 00 00 00    jmpq   \*0x0    a: R_X86_64_32S xxx
 [      ]*[a-f0-9]+:    ff e7                   jmpq   \*%rdi
 [      ]*[a-f0-9]+:    ff 27                   jmpq   \*\(%rdi\)
@@ -17,7 +17,7 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    ff 2c 25 00 00 00 00    ljmp   \*0x0    24: R_X86_64_32S        xxx
 [      ]*[a-f0-9]+:    66 ff 2c 25 00 00 00 00         ljmpw  \*0x0    2c: R_X86_64_32S        xxx
 [      ]*[a-f0-9]+:    e8 cb ff ff ff          callq  0x0
-[      ]*[a-f0-9]+:    e8 00 00 00 00          callq  0x3a     36: R_X86_64_PC32       xxx-0x4
+[      ]*[a-f0-9]+:    e8 00 00 00 00          callq  0x3a     36: R_X86_64_PLT32      xxx-0x4
 [      ]*[a-f0-9]+:    ff 14 25 00 00 00 00    callq  \*0x0    3d: R_X86_64_32S        xxx
 [      ]*[a-f0-9]+:    ff d7                   callq  \*%rdi
 [      ]*[a-f0-9]+:    ff 17                   callq  \*\(%rdi\)
index c070029..d44841e 100644 (file)
@@ -20,9 +20,9 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 24 <foo2>
 
 0+24 <foo2>:
-[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PC32       foo-0x4
-[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 31 <foo2\+0xd>   2d: R_X86_64_PC32       foo-0x4
-[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 37 <foo2\+0x13>       33: R_X86_64_PC32       foo-0x4
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 31 <foo2\+0xd>   2d: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 37 <foo2\+0x13>       33: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 3d <foo2\+0x19>        39: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 44 <foo2\+0x20>  40: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 4a <foo2\+0x26>       46: R_X86_64_PLT32      foo-0x4
index 5bb6a57..514c343 100644 (file)
@@ -20,9 +20,9 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 24 <foo2>
 
 0+24 <foo2>:
-[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PC32       foo-0x4
-[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 31 <foo2\+0xd>   2d: R_X86_64_PC32       foo-0x4
-[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 37 <foo2\+0x13>       33: R_X86_64_PC32       foo-0x4
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 31 <foo2\+0xd>   2d: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 37 <foo2\+0x13>       33: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 3d <foo2\+0x19>        39: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 44 <foo2\+0x20>  40: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 4a <foo2\+0x26>       46: R_X86_64_PLT32      foo-0x4
index c124102..c9eba84 100644 (file)
@@ -10,12 +10,12 @@ Disassembly of section .text:
 0+ <foo>:
 [      ]*[a-f0-9]+:    eb 24                   jmp    26 <local>
 [      ]*[a-f0-9]+:    eb 1e                   jmp    22 <hidden_def>
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   9 <foo\+0x9>     5: R_X86_64_PC32        global_def-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   9 <foo\+0x9>     5: R_X86_64_PLT32       global_def-0x4
 [      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   e <foo\+0xe>     a: R_X86_64_PLT32       global_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   13 <foo\+0x13>   f: R_X86_64_PC32        weak_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   18 <foo\+0x18>   14: R_X86_64_PC32       weak_hidden_undef-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1d <foo\+0x1d>   19: R_X86_64_PC32       weak_hidden_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   22 <hidden_def>  1e: R_X86_64_PC32       hidden_undef-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   13 <foo\+0x13>   f: R_X86_64_PLT32       weak_def-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   18 <foo\+0x18>   14: R_X86_64_PLT32      weak_hidden_undef-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1d <foo\+0x1d>   19: R_X86_64_PLT32      weak_hidden_def-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   22 <hidden_def>  1e: R_X86_64_PLT32      hidden_undef-0x4
 
 0+22 <hidden_def>:
 [      ]*[a-f0-9]+:    c3                      retq   
index 98fd28d..28ab5dd 100644 (file)
@@ -11,10 +11,10 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    eb 1b                   jmp    1f <hidden_def>
 [      ]*[a-f0-9]+:    eb 1b                   jmp    21 <global_def>
 [      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   b <foo\+0xb>     7: R_X86_64_PLT32       global_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   10 <foo\+0x10>   c: R_X86_64_PC32        weak_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   15 <foo\+0x15>   11: R_X86_64_PC32       weak_hidden_undef-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1a <foo\+0x1a>   16: R_X86_64_PC32       weak_hidden_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1f <hidden_def>  1b: R_X86_64_PC32       hidden_undef-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   10 <foo\+0x10>   c: R_X86_64_PLT32       weak_def-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   15 <foo\+0x15>   11: R_X86_64_PLT32      weak_hidden_undef-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1a <foo\+0x1a>   16: R_X86_64_PLT32      weak_hidden_def-0x4
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1f <hidden_def>  1b: R_X86_64_PLT32      hidden_undef-0x4
 
 0+1f <hidden_def>:
 [      ]*[a-f0-9]+:    c3                      retq   
index c5b35e6..a173b62 100644 (file)
@@ -1,3 +1,16 @@
+2018-02-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/22791
+       * testsuite/ld-x86-64/mpx1c.rd: Updated.
+       * testsuite/ld-x86-64/pr22791-1.err: New file.
+       * testsuite/ld-x86-64/pr22791-1a.c: Likewise.
+       * testsuite/ld-x86-64/pr22791-1b.s: Likewise.
+       * testsuite/ld-x86-64/pr22791-2.rd: Likewise.
+       * testsuite/ld-x86-64/pr22791-2a.s: Likewise.
+       * testsuite/ld-x86-64/pr22791-2b.c: Likewise.
+       * testsuite/ld-x86-64/pr22791-2c.s: Likewise.
+       * testsuite/ld-x86-64/x86-64.exp: Run PR ld/22791 tests.
+
 2018-02-13  Alan Modra  <amodra@gmail.com>
 
        PR 22836
index d3b292c..d66524c 100644 (file)
@@ -1,3 +1,3 @@
 #...
-[0-9a-f ]+R_X86_64_PC32 +0+ +.*
+[0-9a-f ]+R_X86_64_PLT32 +0+ +.*
 #...
diff --git a/ld/testsuite/ld-x86-64/pr22791-1.err b/ld/testsuite/ld-x86-64/pr22791-1.err
new file mode 100644 (file)
index 0000000..5500fa5
--- /dev/null
@@ -0,0 +1,2 @@
+.*relocation R_X86_64_PC32 against symbol `foo' can not be used when making a PIE object; recompile with -fPIC
+#...
diff --git a/ld/testsuite/ld-x86-64/pr22791-1a.c b/ld/testsuite/ld-x86-64/pr22791-1a.c
new file mode 100644 (file)
index 0000000..cd0130c
--- /dev/null
@@ -0,0 +1,4 @@
+void
+foo (void)
+{
+}
diff --git a/ld/testsuite/ld-x86-64/pr22791-1b.s b/ld/testsuite/ld-x86-64/pr22791-1b.s
new file mode 100644 (file)
index 0000000..9751db4
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+       .globl  main
+       .type   main, @function
+main:
+       movl    foo(%rip), %eax
+       .size   main, .-main
diff --git a/ld/testsuite/ld-x86-64/pr22791-2.rd b/ld/testsuite/ld-x86-64/pr22791-2.rd
new file mode 100644 (file)
index 0000000..70deb30
--- /dev/null
@@ -0,0 +1,6 @@
+#failif
+#...
+.*\(TEXTREL\).*
+#...
+[0-9a-f ]+R_X86_64_NONE.*
+#...
diff --git a/ld/testsuite/ld-x86-64/pr22791-2a.s b/ld/testsuite/ld-x86-64/pr22791-2a.s
new file mode 100644 (file)
index 0000000..0a85502
--- /dev/null
@@ -0,0 +1,8 @@
+       .text
+       .p2align 4,,15
+       .globl  foo
+       .type   foo, @function
+foo:
+       jmp     bar
+       .size   foo, .-foo
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/pr22791-2b.c b/ld/testsuite/ld-x86-64/pr22791-2b.c
new file mode 100644 (file)
index 0000000..79ef27c
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+bar (void)
+{
+  puts ("PASS");
+}
diff --git a/ld/testsuite/ld-x86-64/pr22791-2c.s b/ld/testsuite/ld-x86-64/pr22791-2c.s
new file mode 100644 (file)
index 0000000..1460d1b
--- /dev/null
@@ -0,0 +1,12 @@
+       .text
+       .p2align 4,,15
+       .globl  main
+       .type   main, @function
+main:
+       subq    $8, %rsp
+       call    foo
+       xorl    %eax, %eax
+       addq    $8, %rsp
+       ret
+       .size   main, .-main
+       .section        .note.GNU-stack,"",@progbits
index af3afcc..a649de8 100644 (file)
@@ -1152,6 +1152,44 @@ if { [isnative] && [which $CC] != 0 } {
             {readelf -lW pr22393-3b.rd}} \
            "pr22393-3-static" \
        ] \
+       [list \
+           "Build pr22791-1.so" \
+           "-shared" \
+           "-fPIC" \
+           { pr22791-1a.c } \
+           {} \
+           "pr22791-1.so" \
+       ] \
+       [list \
+           "Build pr22791-1" \
+           "-pie -Wl,--no-as-needed tmpdir/pr22791-1.so" \
+           "$NOPIE_CFLAGS" \
+           { pr22791-1b.s } \
+           {{error_output "pr22791-1.err"}} \
+           "pr22791-1" \
+       ] \
+       [list \
+           "Build pr22791-2a.o" \
+           "" \
+           "$NOPIE_CFLAGS" \
+           { pr22791-2a.s } \
+       ] \
+       [list \
+           "Build pr22791-2.so" \
+           "-shared tmpdir/pr22791-2a.o" \
+           "-fPIC" \
+           { pr22791-2b.c } \
+           {{readelf -drW pr22791-2.rd}} \
+           "pr22791-2.so" \
+       ] \
+       [list \
+           "Build pr22791-2" \
+           "-pie -Wl,--no-as-needed tmpdir/pr22791-2.so" \
+           "$NOPIE_CFLAGS" \
+           { pr22791-2c.s } \
+           {{readelf -drW pr22791-2.rd}} \
+           "pr22791-2" \
+       ] \
     ]
 
     if  {[istarget "x86_64-*-linux*-gnux32"]} {
@@ -1477,6 +1515,15 @@ if { [isnative] && [which $CC] != 0 } {
            "pr22393-3-static" \
            "pass.out" \
        ] \
+       [list \
+           "Run pr22791-2" \
+           "-pie -Wl,--no-as-needed tmpdir/pr22791-2.so" \
+           "" \
+           { pr22791-2c.s } \
+           "pr22791-2" \
+           "pass.out" \
+           "$NOPIE_CFLAGS" \
+       ] \
     ]
 
     # Run-time tests which require working ifunc attribute support.