This patch adds -mshared option to x86 ELF assembler.  By default,
assembler will optimize out non-PLT relocations against defined non-weak
global branch targets with default visibility.  The -mshared option tells
the assembler to generate code which may go into a shared library
where all non-weak global branch targets with default visibility can
be preempted.  The resulting code is slightly bigger.  This option
only affects the handling of branch instructions.
This Linux kernel patch is needed to create a working x86 Linux kernel if
it hasn't been applied:
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 
ae6588b..
b91a00c 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -339,8 +339,8 @@ early_idt_handlers:
 	i = i + 1
 	.endr
-/* This is global to keep gas from relaxing the jumps */
-ENTRY(early_idt_handler)
+/* This is weak to keep gas from relaxing the jumps */
+WEAK(early_idt_handler)
 	cld
 	cmpl $2,(%rsp)		# X86_TRAP_NMI
--
gas/
	* config/tc-i386.c (shared): New.
	(OPTION_MSHARED): Likewise.
	(elf_symbol_resolved_in_segment_p): Add relocation argument.
	Check PLT relocations and shared.
	(md_estimate_size_before_relax): Pass fragP->fr_var to
	elf_symbol_resolved_in_segment_p.
	(md_longopts): Add -mshared.
	(md_show_usage): Likewise.
	(md_parse_option): Handle OPTION_MSHARED.
	* doc/c-i386.texi: Document -mshared.
gas/testsuite/
	* gas/i386/i386.exp: Don't run pcrel for ELF targets.  Run
	pcrel-elf, relax-4 and x86-64-relax-3 for ELF targets.
	* gas/i386/pcrel-elf.d: New file.
	* gas/i386/relax-4.d: Likewise.
	* gas/i386/x86-64-relax-3.d: Likewise.
	* gas/i386/relax-3.d: Pass -mshared to assembler.  Updated.
	* gas/i386/x86-64-relax-2.d: Likewise.
	* gas/i386/relax-3.s: Add test for PLT relocation.
 
+2015-05-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-i386.c (shared): New.
+       (OPTION_MSHARED): Likewise.
+       (elf_symbol_resolved_in_segment_p): Add relocation argument.
+       Check PLT relocations and shared.
+       (md_estimate_size_before_relax): Pass fragP->fr_var to
+       elf_symbol_resolved_in_segment_p.
+       (md_longopts): Add -mshared.
+       (md_show_usage): Likewise.
+       (md_parse_option): Handle OPTION_MSHARED.
+       * doc/c-i386.texi: Document -mshared.
+
 2015-05-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * write.c (compress_debug): Don't write the zlib header, which
 
 static int use_big_obj = 0;
 #endif
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+/* 1 if generating code for a shared library.  */
+static int shared = 0;
+#endif
+
 /* 1 for intel syntax,
    0 if att syntax.  */
 static int intel_syntax = 0;
 
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 static int
-elf_symbol_resolved_in_segment_p (symbolS *fr_symbol)
+elf_symbol_resolved_in_segment_p (symbolS *fr_symbol, offsetT fr_var)
 {
   /* STT_GNU_IFUNC symbol must go through PLT.  */
   if ((symbol_get_bfdsym (fr_symbol)->flags
     /* Symbol may be weak or local.  */
     return !S_IS_WEAK (fr_symbol);
 
+  /* Global symbols with non-default visibility can't be preempted. */
+  if (ELF_ST_VISIBILITY (S_GET_OTHER (fr_symbol)) != STV_DEFAULT)
+    return 1;
+
+  if (fr_var != NO_RELOC)
+    switch ((enum bfd_reloc_code_real) fr_var)
+      {
+      case BFD_RELOC_386_PLT32:
+      case BFD_RELOC_X86_64_PLT32:
+       /* Symbol with PLT relocatin may be preempted. */
+       return 0;
+      default:
+       abort ();
+      }
+
   /* Global symbols with default visibility in a shared library may be
      preempted by another definition.  */
-  return ELF_ST_VISIBILITY (S_GET_OTHER (fr_symbol)) != STV_DEFAULT;
+  return !shared;
 }
 #endif
 
   if (S_GET_SEGMENT (fragP->fr_symbol) != segment
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       || (IS_ELF
-         && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol))
+         && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol,
+                                               fragP->fr_var))
 #endif
 #if defined (OBJ_COFF) && defined (TE_PE)
       || (OUTPUT_FLAVOR == bfd_target_coff_flavour
 #define OPTION_MBIG_OBJ (OPTION_MD_BASE + 18)
 #define OPTION_OMIT_LOCK_PREFIX (OPTION_MD_BASE + 19)
 #define OPTION_MEVEXRCIG (OPTION_MD_BASE + 20)
+#define OPTION_MSHARED (OPTION_MD_BASE + 21)
 
 struct option md_longopts[] =
 {
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"x32", no_argument, NULL, OPTION_X32},
+  {"mshared", no_argument, NULL, OPTION_MSHARED},
 #endif
   {"divide", no_argument, NULL, OPTION_DIVIDE},
   {"march", required_argument, NULL, OPTION_MARCH},
       /* -s: On i386 Solaris, this tells the native assembler to use
         .stab instead of .stab.excl.  We always use .stab anyhow.  */
       break;
+
+    case OPTION_MSHARED:
+      shared = 1;
+      break;
 #endif
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
      || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
   -mold-gcc               support old (<= 2.8.1) versions of gcc\n"));
   fprintf (stream, _("\
   -madd-bnd-prefix        add BND prefix for all valid branches\n"));
+  fprintf (stream, _("\
+  -mshared                disable branch optimization for shared code\n"));
 # if defined (TE_PE) || defined (TE_PEP)
   fprintf (stream, _("\
   -mbig-obj               generate big object files\n"));
 
 This option forces the assembler to add BND prefix to all branches, even
 if such prefix was not explicitly specified in the source code.
 
+@cindex @samp{-mshared} option, i386
+@cindex @samp{-mshared} option, x86-64
+@item -mno-shared
+On ELF target, the assembler normally optimizes out non-PLT relocations
+against defined non-weak global branch targets with default visibility.
+The @samp{-mshared} option tells the assembler to generate code which
+may go into a shared library where all non-weak global branch targets
+with default visibility can be preempted.  The resulting code is
+slightly bigger.  This option only affects the handling of branch
+instructions.
+
 @cindex @samp{-mbig-obj} option, x86-64
 @item -mbig-obj
 On x86-64 PE/COFF target this option forces the use of big object file
 
+2015-05-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * gas/i386/i386.exp: Don't run pcrel for ELF targets.  Run
+       pcrel-elf, relax-4 and x86-64-relax-3 for ELF targets.
+       * gas/i386/pcrel-elf.d: New file.
+       * gas/i386/relax-4.d: Likewise.
+       * gas/i386/x86-64-relax-3.d: Likewise.
+       * gas/i386/relax-3.d: Pass -mshared to assembler.  Updated.
+       * gas/i386/x86-64-relax-2.d: Likewise.
+       * gas/i386/relax-3.s: Add test for PLT relocation.
+
 2015-05-14  Peter Bergner  <bergner@vnet.ibm.com>
 
        * gas/ppc/power4.d: Add a slbia test.
 
        # but the relocs we currently produce are slightly different
        # from those produced for ELF/COFF based toolchains.
        # So for now we ignore PE targets.
-       run_dump_test "pcrel"
        run_dump_test "absrel"
+       if {[istarget "*-*-coff*"]} then {
+           run_dump_test "pcrel"
+       }
     }
 
     # ELF specific tests
        # PIC is only supported on ELF targets.
        run_dump_test "intelpic"
 
+       run_dump_test "pcrel-elf"
        run_dump_test "relax"
        run_dump_test "gotpc"
        run_dump_test "tlsd"
        run_dump_test "note"
 
        run_dump_test "relax-3"
+       run_dump_test "relax-4"
 
        if {![istarget "*-*-nacl*"]} then {
            run_dump_test "iamcu-1"
        run_list_test "x86-64-size-inval-1" "-al"
 
        run_dump_test "x86-64-relax-2"
+       run_dump_test "x86-64-relax-3"
 
        run_dump_test "x86-64-jump"
     }
 
--- /dev/null
+#source: pcrel.s
+#as: -mshared
+#objdump: -drw
+#name: i386 pcrel ELF reloc
+
+.*: +file format .*i386.*
+
+Disassembly of section \.text:
+
+0+ <loc>:
+[      ]*[a-f0-9]+:    e9 30 12 00 00          jmp    1235 <abs\+0x1>  1: R_386_PC32   \*ABS\*
+
+0+5 <glob>:
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    6 <glob\+0x1>    6: R_386_PC32   ext
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    b <glob\+0x6>    b: R_386_PC32   weak
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    10 <glob\+0xb>   10: R_386_PC32  comm
+[      ]*[a-f0-9]+:    eb ea                   jmp    0 <loc>
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    17 <glob\+0x12>  17: R_386_PC32  glob
+[      ]*[a-f0-9]+:    e9 72 98 00 00          jmp    9892 <abs2\+0x1c>        1c: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 db 00 00 00          jmp    100 <loc2>
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    26 <glob\+0x21>  26: R_386_PC32  glob2
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    2b <glob\+0x26>  2b: R_386_PC32  .data
+[      ]*[a-f0-9]+:    e9 00 00 00 00          jmp    34 <glob\+0x2f>  30: R_386_PC32  .data
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    35 <glob\+0x30>  35: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 c8 ed ff ff          jmp    ffffee06 <abs2\+0xffff5590>      3a: R_386_PC32  ext
+[      ]*[a-f0-9]+:    e9 c8 ed ff ff          jmp    ffffee0b <abs2\+0xffff5595>      3f: R_386_PC32  weak
+[      ]*[a-f0-9]+:    e9 c8 ed ff ff          jmp    ffffee10 <abs2\+0xffff559a>      44: R_386_PC32  comm
+[      ]*[a-f0-9]+:    e9 7f ed ff ff          jmp    ffffedcc <abs2\+0xffff5556>
+[      ]*[a-f0-9]+:    e9 c8 ed ff ff          jmp    ffffee1a <abs2\+0xffff55a4>      4e: R_386_PC32  glob
+[      ]*[a-f0-9]+:    e9 3e 86 00 00          jmp    8695 <abs\+0x7461>       53: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 70 ee ff ff          jmp    ffffeecc <abs2\+0xffff5656>
+[      ]*[a-f0-9]+:    e9 c8 ed ff ff          jmp    ffffee29 <abs2\+0xffff55b3>      5d: R_386_PC32  glob2
+[      ]*[a-f0-9]+:    e9 c8 ed ff ff          jmp    ffffee2e <abs2\+0xffff55b8>      62: R_386_PC32  .data
+[      ]*[a-f0-9]+:    e9 cc ed ff ff          jmp    ffffee37 <abs2\+0xffff55c1>      67: R_386_PC32  .data
+[      ]*[a-f0-9]+:    e9 ba 79 ff ff          jmp    ffff7a2a <abs2\+0xfffee1b4>      6c: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 86 67 ff ff          jmp    ffff67fb <abs2\+0xfffecf85>      71: R_386_PC32  ext
+[      ]*[a-f0-9]+:    e9 86 67 ff ff          jmp    ffff6800 <abs2\+0xfffecf8a>      76: R_386_PC32  weak
+[      ]*[a-f0-9]+:    e9 86 67 ff ff          jmp    ffff6805 <abs2\+0xfffecf8f>      7b: R_386_PC32  comm
+[      ]*[a-f0-9]+:    e9 06 67 ff ff          jmp    ffff678a <abs2\+0xfffecf14>
+[      ]*[a-f0-9]+:    e9 06 67 ff ff          jmp    ffff678f <abs2\+0xfffecf19>
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    8a <glob\+0x85>  8a: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 f7 67 ff ff          jmp    ffff688a <abs2\+0xfffed014>
+[      ]*[a-f0-9]+:    e9 f7 67 ff ff          jmp    ffff688f <abs2\+0xfffed019>
+[      ]*[a-f0-9]+:    e9 86 67 ff ff          jmp    ffff6823 <abs2\+0xfffecfad>      99: R_386_PC32  .data
+[      ]*[a-f0-9]+:    e9 8a 67 ff ff          jmp    ffff682c <abs2\+0xfffecfb6>      9e: R_386_PC32  .data
+[      ]*[a-f0-9]+:    e9 fc 00 00 00          jmp    1a3 <glob2\+0x9e>        a3: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 01 00 00 00          jmp    ad <glob\+0xa8>  a8: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 01 ff ff ff          jmp    ffffffb2 <abs2\+0xffff673c>      ad: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 01 01 00 00          jmp    1b7 <glob2\+0xb2>        b2: R_386_PC32  \*ABS\*
+[      ]*[a-f0-9]+:    e9 01 00 00 00          jmp    bc <glob\+0xb7>  b7: R_386_PC32  \*ABS\*
+       ...
+#pass
 
+#as: -mshared
 #objdump: -dwr
 
 .*: +file format .*
 Disassembly of section .text:
 
 0+ <foo>:
-[      ]*[a-f0-9]+:    eb 1f                   jmp    21 <local>
-[      ]*[a-f0-9]+:    eb 19                   jmp    1d <hidden_def>
-[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    5 <foo\+0x5>     5: (R_386_PC)?(DISP)?32 global_def
-[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    a <foo\+0xa>     a: (R_386_PC)?(DISP)?32 weak_def
-[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    f <foo\+0xf>     f: (R_386_PC)?(DISP)?32 weak_hidden_undef
-[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    14 <foo\+0x14>   14: (R_386_PC)?(DISP)?32        weak_hidden_def
-[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    19 <foo\+0x19>   19: (R_386_PC)?(DISP)?32        hidden_undef
-
-0+1d <hidden_def>:
+[      ]*[a-f0-9]+:    eb 24                   jmp    26 <local>
+[      ]*[a-f0-9]+:    eb 1e                   jmp    22 <hidden_def>
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    5 <foo\+0x5>     5: R_386_PC32   global_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    a <foo\+0xa>     a: R_386_PLT32  global_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    f <foo\+0xf>     f: R_386_PC32   weak_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    14 <foo\+0x14>   14: R_386_PC32  weak_hidden_undef
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    19 <foo\+0x19>   19: R_386_PC32  weak_hidden_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    1e <foo\+0x1e>   1e: R_386_PC32  hidden_undef
+
+0+22 <hidden_def>:
 [      ]*[a-f0-9]+:    c3                      ret    
 
-0+1e <weak_hidden_def>:
+0+23 <weak_hidden_def>:
 [      ]*[a-f0-9]+:    c3                      ret    
 
-0+1f <global_def>:
+0+24 <global_def>:
 [      ]*[a-f0-9]+:    c3                      ret    
 
-0+20 <weak_def>:
+0+25 <weak_def>:
 [      ]*[a-f0-9]+:    c3                      ret    
 
-0+21 <local>:
+0+26 <local>:
 [      ]*[a-f0-9]+:    c3                      ret    
 #pass
 
        jmp local
        jmp hidden_def
        jmp global_def
+       jmp global_def@PLT
        jmp weak_def
        jmp weak_hidden_undef
        jmp weak_hidden_def
 
--- /dev/null
+#source: relax-3.s
+#objdump: -dwr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <foo>:
+[      ]*[a-f0-9]+:    eb 21                   jmp    23 <local>
+[      ]*[a-f0-9]+:    eb 1b                   jmp    1f <hidden_def>
+[      ]*[a-f0-9]+:    eb 1b                   jmp    21 <global_def>
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    7 <foo\+0x7>     7: R_386_PLT32  global_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    c <foo\+0xc>     c: R_386_PC32   weak_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    11 <foo\+0x11>   11: R_386_PC32  weak_hidden_undef
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    16 <foo\+0x16>   16: R_386_PC32  weak_hidden_def
+[      ]*[a-f0-9]+:    e9 fc ff ff ff          jmp    1b <foo\+0x1b>   1b: R_386_PC32  hidden_undef
+
+0+1f <hidden_def>:
+[      ]*[a-f0-9]+:    c3                      ret    
+
+0+20 <weak_hidden_def>:
+[      ]*[a-f0-9]+:    c3                      ret    
+
+0+21 <global_def>:
+[      ]*[a-f0-9]+:    c3                      ret    
+
+0+22 <weak_def>:
+[      ]*[a-f0-9]+:    c3                      ret    
+
+0+23 <local>:
+[      ]*[a-f0-9]+:    c3                      ret    
+#pass
 
 #source: relax-3.s
+#as: -mshared
 #objdump: -dwr
 
 .*: +file format .*
 Disassembly of section .text:
 
 0+ <foo>:
-[      ]*[a-f0-9]+:    eb 1f                   jmp    21 <local>
-[      ]*[a-f0-9]+:    eb 19                   jmp    1d <hidden_def>
+[      ]*[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   e <foo\+0xe>     a: R_X86_64_PC32        weak_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   13 <foo\+0x13>   f: R_X86_64_PC32        weak_hidden_undef-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   18 <foo\+0x18>   14: R_X86_64_PC32       weak_hidden_def-0x4
-[      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   1d <hidden_def>  19: R_X86_64_PC32       hidden_undef-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
 
-0+1d <hidden_def>:
+0+22 <hidden_def>:
 [      ]*[a-f0-9]+:    c3                      retq   
 
-0+1e <weak_hidden_def>:
+0+23 <weak_hidden_def>:
 [      ]*[a-f0-9]+:    c3                      retq   
 
-0+1f <global_def>:
+0+24 <global_def>:
 [      ]*[a-f0-9]+:    c3                      retq   
 
-0+20 <weak_def>:
+0+25 <weak_def>:
 [      ]*[a-f0-9]+:    c3                      retq   
 
-0+21 <local>:
+0+26 <local>:
 [      ]*[a-f0-9]+:    c3                      retq   
 #pass
 
--- /dev/null
+#source: relax-3.s
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <foo>:
+[      ]*[a-f0-9]+:    eb 21                   jmp    23 <local>
+[      ]*[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
+
+0+1f <hidden_def>:
+[      ]*[a-f0-9]+:    c3                      retq   
+
+0+20 <weak_hidden_def>:
+[      ]*[a-f0-9]+:    c3                      retq   
+
+0+21 <global_def>:
+[      ]*[a-f0-9]+:    c3                      retq   
+
+0+22 <weak_def>:
+[      ]*[a-f0-9]+:    c3                      retq   
+
+0+23 <local>:
+[      ]*[a-f0-9]+:    c3                      retq   
+#pass